Skip to main content

Authorization Code Flow

The Authorization Code flow is the most commonly used OAuth 2.0 flow for web applications. It provides a secure way to authenticate users and obtain access tokens.

Overview

This flow is designed for server-side applications where the client secret can be securely stored. The process involves redirecting the user to authenticate and authorize the application, then exchanging an authorization code for an access token.

Flow Steps

  1. Authorization Request: The application redirects the user to the authorization server
  2. User Authentication: The user authenticates and authorizes the application
  3. Authorization Code: The authorization server redirects back with an authorization code
  4. Token Exchange: The application exchanges the authorization code for an access token
  5. Access Resources: Use the access token to access protected resources

Implementation

Prerequisites

Before starting, you’ll need:
  • Your application’s client_id and client_secret
  • A configured redirect URI (e.g., https://yourapp.com/callback)
  • The authorization endpoint: https://login.camall.io/oauth/authorize
  • The token endpoint: https://login.camall.io/oauth/token

Step 1: Generate PKCE Code Verifier and Challenge

For enhanced security, generate a PKCE code verifier and challenge:
# Generate code verifier (random string, 43-128 characters)
code_verifier=$(openssl rand -base64 64 | tr -d '\n' | tr -d '=' | tr '+/' '-_' | cut -c1-128)

# Generate code challenge (SHA256 hash of verifier, base64url encoded)
code_challenge=$(echo -n $code_verifier | openssl dgst -sha256 -binary | base64 | tr -d '\n' | tr -d '=' | tr '+/' '-_')

echo "Code Verifier: $code_verifier"
echo "Code Challenge: $code_challenge"

Step 2: Initiate Authorization Request

Redirect the user to the authorization endpoint with the following parameters:
# Build the authorization URL
CLIENT_ID="your_client_id"
REDIRECT_URI="https://yourapp.com/callback"
STATE=$(openssl rand -hex 16)  # Random state for CSRF protection
SCOPE="openapi offline_access"

AUTH_URL="https://login.camall.io/oauth/authorize?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&state=${STATE}&scope=${SCOPE}&code_challenge=${code_challenge}&code_challenge_method=S256"

echo "Redirect user to: $AUTH_URL"
Parameters:
  • response_type=code: Indicates authorization code flow
  • client_id: Your application’s client ID
  • redirect_uri: Where to redirect after authorization
  • state: Random string to prevent CSRF attacks
  • scope: Requested permissions (space-separated)
  • code_challenge: PKCE code challenge
  • code_challenge_method=S256: SHA256 hashing method
Manual curl example (for testing):
curl -X GET "https://login.camall.io/oauth/authorize?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&state=${STATE}&scope=${SCOPE}&code_challenge=${code_challenge}&code_challenge_method=S256"

Step 3: Handle the Callback

After user authorization, Camall redirects to your redirect_uri with the authorization code:
https://yourapp.com/callback?code=AUTH_CODE_HERE&state=STATE_VALUE
Important: Verify that the state parameter matches the one you sent to prevent CSRF attacks.

Step 4: Exchange Authorization Code for Access Token

Use the authorization code to request an access token:
curl -X POST https://login.camall.io/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_HERE" \
  -d "redirect_uri=https://yourapp.com/callback" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}" \
  -d "code_verifier=${code_verifier}"

Without PKCE (Basic Flow)

curl -X POST https://login.camall.io/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_HERE" \
  -d "redirect_uri=https://yourapp.com/callback" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}"
Parameters:
  • grant_type=authorization_code: Specifies token exchange type
  • code: The authorization code received in the callback
  • redirect_uri: Must match the original request
  • client_id: Your application’s client ID
  • client_secret: Your application’s client secret
  • code_verifier: The PKCE code verifier (when using PKCE)
Response:
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "refresh_token_here",
  "scope": "openapi offline_access"
}

Step 5: Use the Access Token

Make authenticated API requests using the access token:
curl -X GET https://api.camall.io/v1/resource \
  -H "Authorization: Bearer ACCESS_TOKEN_HERE" \
  -H "Content-Type: application/json"

Step 6: Refresh the Access Token (Optional)

When the access token expires, use the refresh token to obtain a new one:
curl -X POST https://login.camall.io/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=REFRESH_TOKEN_HERE" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}"
Response:
{
  "access_token": "new_access_token_here",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "new_refresh_token_here",
  "scope": "openapi offline_access"
}

Complete Example Script

Here’s a complete bash script demonstrating the entire flow:
#!/bin/bash

# Configuration
CLIENT_ID="your_client_id"
CLIENT_SECRET="your_client_secret"
REDIRECT_URI="https://yourapp.com/callback"
SCOPE="openapi offline_access"

# Step 1: Generate PKCE parameters
code_verifier=$(openssl rand -base64 64 | tr -d '\n' | tr -d '=' | tr '+/' '-_' | cut -c1-128)
code_challenge=$(echo -n $code_verifier | openssl dgst -sha256 -binary | base64 | tr -d '\n' | tr -d '=' | tr '+/' '-_')
state=$(openssl rand -hex 16)

echo "Step 1: PKCE parameters generated"
echo "Code Verifier: $code_verifier"
echo "Code Challenge: $code_challenge"
echo ""

# Step 2: Build authorization URL
AUTH_URL="https://login.camall.io/oauth/authorize?response_type=code&client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&state=${state}&scope=${SCOPE}&code_challenge=${code_challenge}&code_challenge_method=S256"

echo "Step 2: Open this URL in your browser:"
echo "$AUTH_URL"
echo ""

# Step 3: After authorization, enter the code
echo "Step 3: After authorizing, enter the authorization code from the callback URL:"
read -p "Authorization code: " AUTH_CODE

# Step 4: Exchange code for token
echo ""
echo "Step 4: Exchanging authorization code for access token..."
TOKEN_RESPONSE=$(curl -s -X POST https://login.camall.io/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=${AUTH_CODE}" \
  -d "redirect_uri=${REDIRECT_URI}" \
  -d "client_id=${CLIENT_ID}" \
  -d "client_secret=${CLIENT_SECRET}" \
  -d "code_verifier=${code_verifier}")

echo "Token Response:"
echo "$TOKEN_RESPONSE" | jq '.'

# Extract access token
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | jq -r '.access_token')

echo ""
echo "Step 5: Access token obtained: $ACCESS_TOKEN"
echo ""
echo "You can now use this token to make API requests:"
echo "curl -H \"Authorization: Bearer $ACCESS_TOKEN\" https://api.camall.io/v1/resource"

Security Best Practices

  1. Always use PKCE: Protects against authorization code interception attacks
  2. Validate state parameter: Prevents CSRF attacks
  3. Use HTTPS: All endpoints must use HTTPS in production
  4. Secure client secret: Never expose your client secret in client-side code
  5. Short-lived tokens: Access tokens should have limited lifetime
  6. Rotate refresh tokens: Request new refresh tokens with each refresh
  7. Validate redirect URIs: Only use pre-registered redirect URIs

HTTP Request Examples

Raw HTTP Request - Authorization

GET /oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback&state=random_state&scope=openapi%20offline_access&code_challenge=CODE_CHALLENGE&code_challenge_method=S256 HTTP/1.1
Host: login.camall.io

Raw HTTP Request - Token Exchange

POST /oauth/token HTTP/1.1
Host: login.camall.io
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&code_verifier=CODE_VERIFIER

Raw HTTP Request - API Call with Bearer Token

GET /v1/resource HTTP/1.1
Host: api.camall.io
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json