@@ -144,15 +144,19 @@ func SetAuthURLParam(key, value string) AuthCodeOption {
144144// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
145145// that asks for permissions for the required scopes explicitly.
146146//
147- // State is a token to protect the user from CSRF attacks. You must
148- // always provide a non-empty string and validate that it matches the
149- // state query parameter on your redirect callback.
150- // See http://tools.ietf.org/html/rfc6749#section-10.12 for more info.
147+ // State is an opaque value used by the client to maintain state between the
148+ // request and callback. The authorization server includes this value when
149+ // redirecting the user agent back to the client.
151150//
152151// Opts may include AccessTypeOnline or AccessTypeOffline, as well
153152// as ApprovalForce.
154- // It can also be used to pass the PKCE challenge.
155- // See https://www.oauth.com/oauth2-servers/pkce/ for more info.
153+ //
154+ // To protect against CSRF attacks, opts should include a PKCE challenge
155+ // (S256ChallengeOption). Not all servers support PKCE. An alternative is to
156+ // generate a random state parameter and verify it after exchange.
157+ // See https://datatracker.ietf.org/doc/html/rfc6749#section-10.12 (predating
158+ // PKCE), https://www.oauth.com/oauth2-servers/pkce/ and
159+ // https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-09.html#name-cross-site-request-forgery (describing both approaches)
156160func (c * Config ) AuthCodeURL (state string , opts ... AuthCodeOption ) string {
157161 var buf bytes.Buffer
158162 buf .WriteString (c .Endpoint .AuthURL )
@@ -167,7 +171,6 @@ func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
167171 v .Set ("scope" , strings .Join (c .Scopes , " " ))
168172 }
169173 if state != "" {
170- // TODO(light): Docs say never to omit state; don't allow empty.
171174 v .Set ("state" , state )
172175 }
173176 for _ , opt := range opts {
@@ -212,10 +215,11 @@ func (c *Config) PasswordCredentialsToken(ctx context.Context, username, passwor
212215// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
213216//
214217// The code will be in the *http.Request.FormValue("code"). Before
215- // calling Exchange, be sure to validate FormValue("state").
218+ // calling Exchange, be sure to validate FormValue("state") if you are
219+ // using it to protect against CSRF attacks.
216220//
217- // Opts may include the PKCE verifier code if previously used in AuthCodeURL.
218- // See https://www.oauth.com/oauth2-servers/pkce/ for more info .
221+ // If using PKCE to protect against CSRF attacks, opts should include a
222+ // VerifierOption .
219223func (c * Config ) Exchange (ctx context.Context , code string , opts ... AuthCodeOption ) (* Token , error ) {
220224 v := url.Values {
221225 "grant_type" : {"authorization_code" },
0 commit comments