Skip to content
Last updated

Authorization Code Flow

The Authorization Code Flow is the recommended OAuth2 flow for server-side applications where the client secret can be securely stored.

Flow Overview

┌──────────┐
│   User   │
└─────┬────┘
      │ 1. Initiate login

┌──────────────┐
│  Your App    │
└──────┬───────┘
       │ 2. Redirect to authorization URL

  ┌──────────┐
  │  Askara  │
  └────┬─────┘
       │ 3. Show login/consent page

  ┌──────────┐
  │   User   │
  └────┬─────┘
       │ 4. Authorize application

  ┌──────────┐
  │  Askara  │
  └────┬─────┘
       │ 5. Redirect with authorization code

┌──────────────┐
│  Your App    │
└──────┬───────┘
       │ 6. Exchange code for token

  ┌──────────┐
  │  Askara  │
  └────┬─────┘
       │ 7. Return access & refresh tokens

┌──────────────┐
│  Your App    │
└──────┬───────┘
       │ 8. Authentication complete

┌──────────┐
│   User   │
└──────────┘

Implementation

Step 1: Generate Authorization URL

Generate a random state parameter for CSRF protection and store it securely (session, cookie, or database).

Build the authorization URL:

https://app.askara.ai/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=profile%20organization&state=STATE

Parameters:

  • response_type: Must be code
  • client_id: Your application's client ID
  • redirect_uri: Your callback URL (must match registration)
  • scope: Space-separated list of permissions (profile organization)
  • state: Random string for CSRF protection

Redirect the user to this URL. They will authenticate and authorize your application.

Step 2: Handle Authorization Callback

After authorization, Askara redirects to your redirect_uri with query parameters:

https://your-app.com/callback?code=AUTHORIZATION_CODE&state=STATE

Verify the state parameter matches your stored value to prevent CSRF attacks.

Step 3: Exchange Code for Access Token

Make a server-side POST request to exchange the authorization code for tokens:

POST https://api.askara.ai/oauth2/token
Content-Type: application/json

{
  "grant_type": "authorization_code",
  "code": "AUTHORIZATION_CODE",
  "redirect_uri": "REDIRECT_URI",
  "client_id": "CLIENT_ID",
  "client_secret": "CLIENT_SECRET"
}

Response:

{
  "token_type": "Bearer",
  "expires_in": 3600,
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "def502003f8a8c7..."
}

Important: Store both tokens securely in your database.

Step 4: Use Access Token

Include the access token in API requests:

GET https://api.askara.ai/me
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

Security Considerations

State Parameter

  • Generate a cryptographically secure random string (minimum 16 characters)
  • Store securely and validate on callback
  • Use once and discard after validation

Client Secret

  • Never expose in client-side code
  • Store in environment variables or secure configuration
  • Use HTTPS for all token exchanges

Authorization Code

  • Single-use only
  • Short-lived (valid for 60 seconds)
  • Must be exchanged on server-side

Error Handling

Authorization Errors

If the user denies authorization or an error occurs, Askara redirects with an error parameter:

https://your-app.com/callback?error=access_denied&state=STATE

Common errors:

  • access_denied: User denied authorization
  • invalid_request: Missing or invalid parameters
  • unauthorized_client: Client not authorized for this flow

Token Exchange Errors

{
  "error": "invalid_grant",
  "error_description": "The authorization code has expired"
}

Common errors:

  • invalid_grant: Code expired or already used
  • invalid_client: Invalid client credentials
  • invalid_request: Missing required parameters

Code Example

// Step 1: Generate authorization URL
$state = bin2hex(random_bytes(16));
$_SESSION['oauth_state'] = $state;

$authUrl = 'https://app.askara.ai/authorize?' . http_build_query([
    'response_type' => 'code',
    'client_id' => getenv('ASKARA_CLIENT_ID'),
    'redirect_uri' => 'https://your-app.com/callback',
    'scope' => 'profile organization',
    'state' => $state
]);

header('Location: ' . $authUrl);

// Step 2: Handle callback
if ($_GET['state'] !== $_SESSION['oauth_state']) {
    die('Invalid state parameter');
}

$code = $_GET['code'];

// Step 3: Exchange code for token
$response = $httpClient->post('https://api.askara.ai/oauth2/token', [
    'json' => [
        'grant_type' => 'authorization_code',
        'code' => $code,
        'redirect_uri' => 'https://your-app.com/callback',
        'client_id' => getenv('ASKARA_CLIENT_ID'),
        'client_secret' => getenv('ASKARA_CLIENT_SECRET')
    ]
]);

$tokens = json_decode($response->getBody(), true);
// Store $tokens['access_token'] and $tokens['refresh_token']

Next Steps