# 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: ```http 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:** ```json { "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: ```http 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 ```json { "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 ```php // 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 - [Refresh Token Flow](/guides/refresh-token-flow) - Renew expired access tokens - [API Reference](/apis/askara-symfony/askara-api) - Available API endpoints - [OAuth2 Overview](/guides/oauth2) - Other authentication flows