# Refresh Token Flow Access tokens expire after 1 hour. Use the refresh token to obtain new access tokens without requiring user re-authentication. ## Why Refresh Tokens? Short-lived access tokens limit the impact of token compromise. Refresh tokens enable: - Seamless user experience without repeated logins - Enhanced security through token rotation - Controlled access revocation ## Implementation ### Request New Access Token When your access token expires (HTTP 401 responses), use the refresh token: ```http POST https://api.askara.ai/oauth2/token Content-Type: application/json { "grant_type": "refresh_token", "refresh_token": "REFRESH_TOKEN", "client_id": "CLIENT_ID", "client_secret": "CLIENT_SECRET" } ``` **Response:** ```json { "token_type": "Bearer", "expires_in": 3600, "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token": "def502003f8a8c7..." } ``` **Important:** The response includes a **new** refresh token. Update your stored refresh token immediately as the old one is invalidated. ## Token Rotation Each refresh token is single-use. This rotation mechanism: - Detects token theft (reuse of old refresh token) - Limits the window of vulnerability - Enables security monitoring ### Rotation Flow ``` ┌─────────────────────┐ │ Old Refresh Token │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ POST /oauth2/token │ └──────────┬──────────┘ │ ├──────────────────────┐ │ │ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ │ New Access Token │ │ New Refresh Token│ └────────┬─────────┘ └────────┬─────────┘ │ │ └──────────┬───────────┘ │ ▼ ┌──────────────────┐ │ Update Database │ └────────┬─────────┘ │ ▼ ┌─────────────────────────┐ │ Old Token Invalidated │ └─────────────────────────┘ ``` ## Error Handling ### Invalid Refresh Token ```json { "error": "invalid_grant", "error_description": "The refresh token is invalid or expired" } ``` **Causes:** - Token already used (rotation) - Token revoked by user - Token expired (rare, typically long-lived) - Invalid client credentials **Action:** Redirect user to re-authenticate via [Authorization Code Flow](/guides/authorization-code-flow). ### Revoked Access If a user revokes your application's access, all tokens become invalid. Implement proper error handling to detect this scenario. ## Security Best Practices ### Storage - **Encrypt refresh tokens** in your database - Never expose refresh tokens to client-side code - Use separate encryption keys from other sensitive data ### Rotation Implementation ```php function refreshAccessToken($oldRefreshToken) { $response = $httpClient->post('https://api.askara.ai/oauth2/token', [ 'json' => [ 'grant_type' => 'refresh_token', 'refresh_token' => $oldRefreshToken, 'client_id' => getenv('ASKARA_CLIENT_ID'), 'client_secret' => getenv('ASKARA_CLIENT_SECRET') ] ]); $tokens = json_decode($response->getBody(), true); // Atomic update: only commit if both tokens are updated $db->beginTransaction(); try { $db->update('oauth_tokens', [ 'access_token' => $tokens['access_token'], 'refresh_token' => $tokens['refresh_token'], 'expires_at' => time() + $tokens['expires_in'] ]); $db->commit(); } catch (Exception $e) { $db->rollback(); throw $e; } return $tokens['access_token']; } ``` ### Expiration Handling Check token expiration **before** making API requests to avoid unnecessary failures: ```php function getValidAccessToken() { $tokenData = $db->getTokenData(); // Refresh if token expires within 5 minutes if ($tokenData['expires_at'] < time() + 300) { return refreshAccessToken($tokenData['refresh_token']); } return $tokenData['access_token']; } ``` ## Automatic Retry Pattern Implement automatic token refresh on 401 responses: ```php function makeApiRequest($url, $data) { $accessToken = getValidAccessToken(); try { return $httpClient->post($url, [ 'headers' => ['Authorization' => 'Bearer ' . $accessToken], 'json' => $data ]); } catch (UnauthorizedException $e) { // Token expired during request, refresh and retry once $accessToken = refreshAccessToken($db->getRefreshToken()); return $httpClient->post($url, [ 'headers' => ['Authorization' => 'Bearer ' . $accessToken], 'json' => $data ]); } } ``` ## Monitoring Track refresh token usage to detect anomalies: - Unusually frequent refreshes (potential token theft) - Failed refresh attempts (compromised credentials) - Geographic anomalies (access from unexpected locations) ## Next Steps - [Authorization Code Flow](/guides/authorization-code-flow) - Initial authentication - [API Reference](/apis/askara-symfony/askara-api) - API endpoints - [OAuth2 Overview](/guides/oauth2) - All authentication flows