What Is OAuth2?
OAuth2 is an industry-standard authorization framework that allows third-party applications to access user resources without exposing user credentials. Instead of sharing passwords, OAuth2 uses access tokens with defined scopes and expiration times to grant limited access.
Understanding the Authorization Code Flow
The authorization code flow is the most secure and widely recommended OAuth2 grant type for server-side applications. It involves the following participants:
- Resource Owner: The end user who owns the data
- Client: Your application requesting access
- Authorization Server: The server that authenticates the user and issues tokens
- Resource Server: The API that holds the protected resources
Step 1: Register Your Application
Before implementing OAuth2, register your application with the authorization server to obtain your client credentials.
- Navigate to the provider's developer portal
- Create a new OAuth2 application
- Provide a redirect URI (the URL the user will be sent back to after authorization)
- Record your Client ID and Client Secret
Store the client secret securely using environment variables or a secrets manager. Never expose it in client-side code.
Step 2: Redirect the User to the Authorization Endpoint
When a user initiates the login flow, redirect their browser to the authorization server:
GET https://auth.example.com/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://yourapp.com/callback
&scope=read write
&state=random_csrf_token
Parameters Explained
- response_type=code requests an authorization code
- client_id identifies your application
- redirect_uri must match the URI registered in Step 1
- scope defines the permissions your application is requesting
- state is a random string used to prevent CSRF attacks; generate it per session and verify it on callback
Step 3: Handle the Authorization Callback
After the user grants permission, the authorization server redirects back to your application with an authorization code:
GET https://yourapp.com/callback
?code=AUTHORIZATION_CODE
&state=random_csrf_token
Before proceeding, verify that the state parameter matches the value you generated in Step 2. If it does not match, reject the request immediately.
Step 4: Exchange the Code for Tokens
Make a server-side POST request to the token endpoint to exchange the authorization code for an access token:
POST https://auth.example.com/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AUTHORIZATION_CODE
&redirect_uri=https://yourapp.com/callback
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
The response will include:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "dGhpcyBpcyBhIHJlZnJl...",
"scope": "read write"
}
Step 5: Use the Access Token
Include the access token in the Authorization header when making API requests:
GET /v1/user/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Step 6: Refresh Expired Tokens
Access tokens have limited lifetimes. When a token expires, use the refresh token to obtain a new one without requiring the user to log in again:
POST https://auth.example.com/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token=dGhpcyBpcyBhIHJlZnJl...
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Refresh Token Best Practices
- Store refresh tokens securely on the server side, never in the browser
- Implement refresh token rotation: each refresh request issues a new refresh token and invalidates the old one
- Set appropriate expiration times for refresh tokens (typically 7 to 30 days)
Security Considerations
Use PKCE for Public Clients
For single-page applications or mobile apps where the client secret cannot be kept confidential, use Proof Key for Code Exchange (PKCE). This adds a code verifier and code challenge to the flow, preventing authorization code interception attacks.
Validate Tokens Properly
- Always verify the token signature and issuer
- Check that the token has not expired
- Confirm the token's audience matches your application
- Validate that the token's scopes include the permissions required for the requested operation
Secure Token Storage
- Store access tokens in memory on the client when possible
- Use HTTP-only, secure cookies for web applications
- Never store tokens in localStorage or sessionStorage in production
Conclusion
The OAuth2 authorization code flow provides a robust and secure mechanism for API authentication. By carefully implementing each step, from registration through token refresh, and following security best practices like PKCE and token rotation, you can build a trustworthy authentication experience for your users.