Skip to content

Authorization Code Flow

OAuth2's Authorization Code Grant Flow is the most secure and widely used method for applications to obtain access tokens from an authorization server. It is designed for public clients (like web apps) and leverages a multi-step process to ensure confidentiality and prevent token leakage. This flow separates the user authentication and authorization process from the token issuance, minimizing exposure of sensitive credentials.


Core Components

  1. Client: The application requesting access to a protected resource.
  2. User Agent: The user's browser or device initiating the flow.
  3. Authorization Server: Issues the authorization code after user consent.
  4. Token Server: Issues access tokens (and ID tokens) after exchanging the authorization code.

Flow Overview

  1. Redirect to Authorization Endpoint
    The client redirects the user agent to the authorization server's endpoint with parameters:
  2. client_id: Identifies the client.
  3. redirect_uri: The URI to which the authorization server will redirect the user agent.
  4. scope: Requested permissions.
  5. response_type=code: Indicates the authorization code grant type.
  6. state: A random string to prevent CSRF attacks.

Example:

GET https://auth.example.com/authorize?
  client_id=web-app&
  redirect_uri=https://client.example.com/callback&
  scope=openid&
  response_type=code&
  state=xyz123

  1. User Authentication and Consent
    The user authenticates with the authorization server and grants consent for the client to access their resources.

  2. Authorization Code Issued
    The authorization server redirects the user agent back to the redirect_uri with the code and state parameters:

    GET https://client.example.com/callback?
      code=AUTHORIZATION_CODE&
      state=xyz123
    

  3. Token Exchange
    The client exchanges the authorization code for tokens by sending a POST request to the token endpoint:

  4. grant_type=authorization_code
  5. code: The received authorization code.
  6. redirect_uri: Must match the one used in the initial redirect.
  7. client_id and client_secret: For client authentication.

Example:

POST https://auth.example.com/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=AUTHORIZATION_CODE&
redirect_uri=https://client.example.com/callback&
client_id=web-app&
client_secret=secret

The token server responds with:

{
  "access_token": "ACCESS_TOKEN",
  "id_token": "ID_TOKEN",
  "refresh_token": "REFRESH_TOKEN",
  "token_type": "Bearer"
}


Security Considerations

  • CSRF Protection: The state parameter ensures the redirect URL is not tampered with. The client validates the state value against the original request.
  • Redirect URI Validation: The redirect_uri must be pre-registered and match exactly to prevent open redirect vulnerabilities.
  • Secure Token Storage: Access tokens should be stored securely (e.g., in HTTP-only cookies or secure local storage).

Example Workflow

Step 1: Redirect User

curl "https://auth.example.com/authorize?client_id=web-app&redirect_uri=https://client.example.com/callback&scope=openid&response_type=code&state=xyz123"

Step 2: Token Exchange

curl -X POST "https://auth.example.com/token" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE" \
  -d "redirect_uri=https://client.example.com/callback" \
  -d "client_id=web-app" \
  -d "client_secret=secret"


Key Takeaways

  • The authorization code grant flow securely separates user authentication from token issuance.
  • The state parameter is critical for mitigating CSRF attacks.
  • Clients must validate the redirect_uri and ensure it matches the registered value.
  • Tokens (especially access tokens) must be handled with strict confidentiality and secure storage.