Authorization

OAuth 2.0 Grant Types: Authorization Code Grant

Welcome to the second installment of our OAuth 2.0 series! In this article, we will dive deep into the Authorization Code Grant, which is the most widely recommended and secure OAuth 2.0 flow for confidential clients, particularly traditional server-side web applications.

What is Authorization Code Grant?

The Authorization Code Grant is designed for clients that can securely maintain a client_secret and protect it from unauthorized access. This typically applies to web applications with a backend server. It provides a robust security model by ensuring that the access_token is never directly exposed in the user's browser, and the client application itself is authenticated when exchanging the authorization code for tokens.

When to use it?

  • Server-side Web Applications: This is the primary use case.
  • Confidential Clients: Applications that can securely store a client_secret.
  • Mobile Apps / Single-Page Applications (SPAs): While this flow is used, it requires the PKCE extension for enhanced security (we'll cover PKCE in a later article).

Key Roles Involved (Refresher)

Before we outline the flow, let's quickly recap the roles:

  • Resource Owner: The user granting access.
  • Client (Application): Your web app wanting to access user data.
  • Authorization Server: The service (e.g., Google, Facebook) that authenticates the user and issues tokens.
  • Resource Server: The API hosting the protected user data.

The Flow of Authorization Code Grant

Let's illustrate with an example: You're using an online photo editing app (Client App) on your computer, and you want it to access your photo albums on Google Photos (Resource Server).

graph TB A["👤 User's Browser"] B["📱 Client App"] C["🔐 Authorization Server
(Google)"] D["🗄️ Resource Server
(Google Photos API)"] A -->|"1. Clicks Connect"| B B -->|"2. Redirect to /authorize"| C C -->|"3. Login/Consent"| A A -->|"4. Grant consent"| C C -->|"5. Callback with auth_code"| A A -->|"6. Redirect to Client"| B B -->|"7. Exchange for tokens"| C C -->|"8. Return tokens"| B B -->|"9. API call"| D D -->|"10. Return data"| B

Step-by-Step Explanation with Examples

Step 1: Client Requests Authorization

The user interacts with your Client App (e.g., clicks a "Connect to Google Photos" button). Your Client App (usually its backend) constructs an authorization URL and redirects the user's browser to the Authorization Server's /authorize endpoint.

Request Example (User's Browser):

GET https://accounts.google.com/o/oauth2/v2/auth?
    response_type=code&
    client_id=YOUR_CLIENT_ID&
    redirect_uri=https://your-app.com/oauth/callback&
    scope=https://www.googleapis.com/auth/photoslibrary.readonly&
    state=YOUR_SECURE_RANDOM_STATE&
    access_type=offline

Parameters Explained:

  • response_type=code: Indicates that the Client wants an authorization_code.
  • client_id: A unique ID assigned to your Client App when you registered it with the Authorization Server.
  • redirect_uri: The URL where the Authorization Server will redirect the user's browser back to your Client App. This URL must be pre-registered.
  • scope: The specific permissions your Client App is requesting (e.g., photoslibrary.readonly).
  • state: An opaque value used by the Client to maintain state. Crucial for preventing CSRF attacks.
  • access_type=offline: (Optional, Google-specific) Requests a refresh_token for long-lived access.

Step 2: User Authenticates and Grants Consent

The Authorization Server displays a login page (if the user isn't already logged in) and a consent screen (detailing the permissions the Client App is requesting). The user logs in (Authentication) and then chooses to "Allow" or "Deny" the requested permissions (Authorization).

Step 3: Authorization Server Issues Authorization Code

If the user grants consent, the Authorization Server redirects the user's browser back to the redirect_uri provided by the Client App. The authorization_code and the original state value are appended as query parameters.

Response Example (User's Browser Redirect):

HTTP/1.1 302 Found
Location: https://your-app.com/oauth/callback?
    code=4/P7q7W_F_yC0d...&
    state=YOUR_SECURE_RANDOM_STATE

Security Note: authorization_code in Query Parameters

While the authorization_code appears in query parameters, this is generally considered safe because:

  • 1. The code has a very short lifespan (typically a few seconds to minutes)
  • 2. It is a one-time use code
  • 3. The crucial protection comes in the next step with the client_secret

Step 4: Client Exchanges Authorization Code for Tokens

Upon receiving the authorization_code (and validating the state parameter!), your Client App's backend server makes a direct POST request to the Authorization Server's /token endpoint. Crucially, this request includes the client_secret to authenticate your Client App.

Request Example (Client App Backend to Authorization Server):

POST /oauth2/v4/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <Base64-encoded client_id:client_secret>

grant_type=authorization_code&
code=4/P7q7W_F_yC0d...&
redirect_uri=https://your-app.com/oauth/callback&
client_id=YOUR_CLIENT_ID

Where do client_id and client_secret come from?

These are credentials that your Client App receives when you register your application with the Authorization Server (e.g., in Google Cloud Console, Facebook for Developers). The client_id is public, but the client_secret must be kept confidential on your backend server.

Step 5: Authorization Server Returns Access Token and Refresh Token

The Authorization Server validates the authorization_code, redirect_uri, and the client_secret. If all are valid, it returns a JSON response containing the tokens.

Response Example (Authorization Server to Client App Backend):

{
    "access_token": "ya29.a0AWTD...",
    "token_type": "Bearer",
    "expires_in": 3599,
    "refresh_token": "1//0ewt_P...",
    "scope": "https://www.googleapis.com/auth/photoslibrary.readonly"
}

Tokens Explained:

  • access_token: The actual credential used to access protected resources. Usually short-lived.
  • token_type: Defines how the access_token should be used (e.g., Bearer).
  • expires_in: The lifetime of the access_token in seconds.
  • refresh_token: A long-lived token used to obtain new access_tokens without requiring the user to re-authenticate.

Step 6: Client Uses Access Token to Access Resources

Your Client App (backend) now uses the access_token to make authenticated requests to the Resource Server's API (e.g., Google Photos API). The access_token is typically included in the Authorization header as a Bearer token.

Request Example (Client App Backend to Resource Server):

GET https://photoslibrary.googleapis.com/v1/albums HTTP/1.1
Host: photoslibrary.googleapis.com
Authorization: Bearer ya29.a0AWTD...

Advantages of Authorization Code Grant

  • High Security: The access_token is never exposed in the user's browser URL. The critical exchange happens server-to-server using the client_secret.
  • Supports Refresh Tokens: Allows clients to obtain new access tokens when old ones expire, without requiring user re-authentication.
  • Confidential Client Friendly: Ideal for applications that can securely store their client_secret.

Disadvantages of Authorization Code Grant

  • Complexity: More complex than simpler flows due to multiple redirects and server-to-server interactions.
  • Requires a Backend: Necessitates a server-side component for your Client App to handle the client_secret securely.

Common Issues and Security Considerations

Even with its robust design, improper implementation can introduce vulnerabilities.

1. Missing or Invalid state Parameter (CSRF Protection)

Issue: If the Client does not generate and validate the state parameter, an attacker can perform a Cross-Site Request Forgery (CSRF) attack.

Prevention: Always generate a unique, cryptographically random state value for each authorization request and verify it matches upon callback.

2. Unvalidated redirect_uri (Open Redirect Vulnerability)

Issue: If the Authorization Server allows arbitrary redirect_uri values, an attacker can redirect the authorization_code to their malicious server.

Prevention: The Authorization Server must strictly enforce pre-registered redirect_uri values with exact matching.

3. Authorization Code Interception (for Public Clients)

Issue: Public Clients (SPAs, mobile apps) cannot keep a client_secret safe. If an attacker intercepts the authorization_code, they could exchange it for an access_token.

Prevention: For Public Clients, the Authorization Code Grant MUST be used with PKCE (Proof Key for Code Exchange).

Conclusion

The Authorization Code Grant is the cornerstone of secure OAuth 2.0 implementations for confidential clients. By leveraging a server-side exchange for tokens protected by a client_secret, it minimizes the exposure of sensitive credentials and enables long-lived sessions through refresh tokens. However, careful implementation, particularly regarding state and redirect_uri validation, is essential to mitigate common security vulnerabilities. For public clients, the Authorization Code Grant's security is significantly enhanced by incorporating PKCE, which we'll explore next!