# Device Code Flow The Device Code Flow enables authentication for applications where secure credential storage is challenging, such as desktop software or offline client-server applications. ## Use Cases - **Desktop applications**: Medical practice management software - **Offline applications**: Client-server systems with limited internet connectivity - **Limited input devices**: Applications where entering credentials is difficult ## Flow Overview ``` ┌─────────────────┐ │ Your Application│ └────────┬────────┘ │ 1. Request device code ▼ ┌──────────┐ │ Askara │ └────┬─────┘ │ 2. Return device code & user code ▼ ┌─────────────────┐ │ Your Application│ └────────┬────────┘ │ 3. Display user code & URL ▼ ┌──────────┐ │ User │ └────┬─────┘ │ 4. Visit URL & enter code ▼ ┌──────────┐ │ Askara │ └────┬─────┘ │ 5. Show login/consent page ▼ ┌──────────┐ │ User │ └────┬─────┘ │ 6. Authorize application ▼ ┌──────────┐ │ Askara │ └────┬─────┘ │ │ ┌─────────────────────────┐ │ │ 7. Polling loop │ │ │ │ ┌─────────────────┐ │ │ Your Application│◄─────────────────┘ └────────┬────────┘ authorization_pending │ │ (continues polling...) │ ┌────▼─────┐ │ Askara │ └────┬─────┘ │ 8. Return access & refresh tokens ▼ ┌─────────────────┐ │ Your Application│ └─────────────────┘ ``` Unlike the Authorization Code Flow, the user authenticates on a separate device (phone, computer) by entering a short code. ## Implementation ### Step 1: Request Device Code Your application requests a device code from Askara. Make sure to replace CLIENT_ID with your client identifier and to use the desired scopes. ```http POST https://api.askara.ai/oauth2/device-authorization Content-Type: application/x-www-form-urlencoded client_id=CLIENT_ID&scope=profile organization ``` **Response:** ```json { "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS", "user_code": "BDWP-HQPK", "verification_uri": "https://app.askara.ai/device-verify", "expires_in": 600, "interval": 5 } ``` **Response fields:** - `device_code`: Used for polling (keep secure) - `user_code`: Short code displayed to user (e.g., "BDWP-HQPK") - `verification_uri`: URL where user enters the code - `expires_in`: Code validity period in seconds (10 minutes) - `interval`: Minimum seconds between polling requests ### Step 2: Display Instructions to User Show the user how to authorize the application. Provide multiple options: **Option 1: Manual Code Entry** ``` 1. Visit: https://app.askara.ai/device-verify 2. Enter code: BDWP-HQPK 3. Authorize the application ``` **Option 2: QR Code** Generate a QR code from the verification URI for quick mobile access. **Option 3: Direct Link** Provide a clickable link to the verification URI. ### Step 3: Poll for Authorization Poll the token endpoint while waiting for user authorization: ```http POST https://api.askara.ai/oauth2/token Content-Type: application/x-www-form-urlencoded grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS&client_id=CLIENT_ID ``` **Important:** Respect the `interval` value to avoid rate limiting. Poll every 5 seconds (or as specified). ### Step 4: Handle Response #### Authorization Pending ```json { "error": "authorization_pending", "error_description": "User has not yet authorized the device" } ``` **Action:** Continue polling. #### Slow Down ```json { "error": "slow_down", "error_description": "Polling too frequently" } ``` **Action:** Increase polling interval by 5 seconds. #### Success ```json { "token_type": "Bearer", "expires_in": 3600, "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token": "def502003f8a8c7..." } ``` **Action:** Store tokens and stop polling. #### Expired or Denied ```json { "error": "expired_token", "error_description": "The device code has expired" } ``` **Action:** Start over from Step 1. ## Code Example ```php // Step 1: Request device code $response = $httpClient->post('https://api.askara.ai/oauth2/device-authorization', [ 'form_params' => [ 'client_id' => getenv('ASKARA_CLIENT_ID'), 'scope' => 'profile organization' ] ]); $deviceData = json_decode($response->getBody(), true); // Step 2: Display to user echo "Visit: {$deviceData['verification_uri']}\n"; echo "Enter code: {$deviceData['user_code']}\n"; echo "Or scan this QR code:\n"; displayQRCode($deviceData['verification_uri']); // Step 3: Poll for authorization $interval = $deviceData['interval']; $expiresAt = time() + $deviceData['expires_in']; while (time() < $expiresAt) { sleep($interval); try { $tokenResponse = $httpClient->post('https://api.askara.ai/oauth2/token', [ 'form_params' => [ 'grant_type' => 'urn:ietf:params:oauth:grant-type:device_code', 'device_code' => $deviceData['device_code'], 'client_id' => getenv('ASKARA_CLIENT_ID') ] ]); $tokens = json_decode($tokenResponse->getBody(), true); // Success! Store tokens storeTokens($tokens); echo "Authorization successful!\n"; break; } catch (HttpException $e) { $error = json_decode($e->getResponse()->getBody(), true); if ($error['error'] === 'authorization_pending') { // Keep waiting continue; } if ($error['error'] === 'slow_down') { // Increase interval $interval += 5; continue; } // Other error (expired, denied, etc.) echo "Authorization failed: {$error['error_description']}\n"; break; } } ``` ## User Experience Best Practices ### Clear Instructions - Display the verification URL prominently - Format the user code for readability (e.g., "BDWP-HQPK" not "bdwphqpk") - Show expiration time to create urgency ### Multiple Entry Methods - Provide QR code for mobile users - Offer clickable link for desktop users - Include manual entry for maximum compatibility ### Progress Indication ``` ⏳ Waiting for authorization... Visit: https://app.askara.ai/device-verify Code: BDWP-HQPK Expires in: 8:32 ``` ### Timeout Handling ``` ❌ Authorization expired The code has expired. Click here to generate a new code. ``` ## Security Considerations ### Device Code Protection - Device codes are bearer tokens - keep them secure - Don't log or expose device codes in error messages - Codes expire after 10 minutes ### Rate Limiting - Respect the `interval` parameter - Handle `slow_down` errors appropriately - Implement exponential backoff for repeated failures ### Client Secret For desktop applications, client secrets cannot be kept confidential. Consider: - Using public client configuration (no secret required) - Implementing additional security measures (PKCE) - Contact us to discuss your specific use case ## Comparison with Authorization Code Flow | Feature | Device Code | Authorization Code | | --- | --- | --- | | **Redirect required** | No | Yes | | **User enters code** | Yes | No | | **Client secret** | Optional | Required | | **Best for** | Desktop apps | Web apps | | **User device** | Any device | Same device | ## Next Steps - [Refresh Token Flow](/guides/refresh-token-flow) - Renew expired tokens - [Authorization Code Flow](/guides/authorization-code-flow) - Alternative for web apps - [OAuth2 Overview](/guides/oauth2) - All authentication flows