Skip to content
Last updated

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.

POST https://api.askara.ai/oauth2/device-authorization
Content-Type: application/x-www-form-urlencoded

client_id=CLIENT_ID&scope=profile organization

Response:

{
  "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:

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

{
  "error": "authorization_pending",
  "error_description": "User has not yet authorized the device"
}

Action: Continue polling.

Slow Down

{
  "error": "slow_down",
  "error_description": "Polling too frequently"
}

Action: Increase polling interval by 5 seconds.

Success

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

Action: Store tokens and stop polling.

Expired or Denied

{
  "error": "expired_token",
  "error_description": "The device code has expired"
}

Action: Start over from Step 1.

Code Example

// 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

FeatureDevice CodeAuthorization Code
Redirect requiredNoYes
User enters codeYesNo
Client secretOptionalRequired
Best forDesktop appsWeb apps
User deviceAny deviceSame device

Next Steps