
OAuth Device Flow
On this page
The OAuth 2.0 Device Authorization Grant commonly referred to as the Device Flow is an extension to the original OAuth 2.0 specification. It solves the problem of obtaining access tokens on devices that do not have a browser or have limited input capabilities. This flow is particularly useful for devices like smart TVs, gaming consoles, and other internet-connected devices where traditional authentication methods are impractical.
Key Components:
- Device Authorization Endpoint: The endpoint where the device requests authorization.
- User Code: A code displayed to the user to enter on a secondary device.
- Verification URI: The URL the user visits to input the user code and authenticate.
- Device Code: A code used by the device to poll the token endpoint.
- Token Endpoint: The endpoint the device polls to obtain the access token.
How the OAuth Device Flow Works
A typical example of the device flow is providing user login for an app on a TV or set-top box. The device (TV) initiates the flow and then shows a code or QR code that the user will enter on a computer or a mobile device, where it's easier to authenticate. Once the user has authenticated, the authorization server presents a consent screen, where the user can device to access their account.
This distinguishes the flow from other OAuth flows that rely on a local browser for user authentication. Instead, there is an out-of-band component where the user authenticates. The device waits, polling the OAuth server to see if the authorization is complete.
In the Curity Identity Server, the device client needs to be a dynamically registered client.
Dynamic Client
The device client needs to be a dynamically registered client. It is not possible to perform a device flow with a static (configured) client.
Device Verification Endpoint
To start off the flow, the device requests a new authorization from the device verification endpoint.
- The device requests a new grant from the device verification endpoint
- The server responds with a code to present to the user, along with a verification URI. It also issues a device code as well as interval for the device to poll the status of the grant.
The user needs to visit the verification URI using a different appliance and enter the code (an alphanumeric string) to authorize the device. The device may render this URI as a QR code to improve user experience.
User Authentication and Device Authorization
The user uses another device (mobile or browser) to visit the URL presented.
- The user visits the verification URI that points to the Token Service.
- The Token Service redirects to the Authentication Service for user authentication (SSO may occur).
- After the user has authenticated, the Authentication Service redirects back to the Token Service.
- The Token Service presents a consent screen. Once the user approves the request, the user flow is complete, and the user can close the browser.
Note that while the Authentication Service and Token Service are logically two different concepts, they are part of the same entity, the authorization server.
Token Endpoint
- The device polls the Token Service's token endpoint using the device code issued in the first flow.
- Once the user has approved the grant, the Token Service returns an access token and a refresh token (if so configured).
While waiting for the user approval, the token endpoint responds with a 400 HTTP status code with the error authorization_pending
. This means the device must wait and try again after the defined poll interval.
Device Verification Endpoint Request
- Method:
POST
- Content-Type:
application/x-www-form-urlencoded
- Response Type:
application/json
Request Parameters
Parameter | Value | Mandatory | Description |
---|---|---|---|
client_id | The Client ID | yes | The ID of the requesting client |
client_secret | The client secret | yes* | The secret of the client. *Mandatory if client authentication is of type secret and the authentication is not done using basic authentication |
scope | Space-separated string of scopes | no | List the scopes the client is requesting access to. |
Response
- Response Type:
application/json
Parameter | Value | Mandatory | Description |
---|---|---|---|
user_code | alphanumeric | yes | The code to present to the user that the user needs to enter out-of-band |
verification_url | URL | yes | The URL the user should visit to enter the user_code and authenticate |
verification_url_complete | URI | no | The verification_url with the user_code added as a query for shorthand access |
device_code | string | yes | The code the device should use to poll and retrieve tokens from the token endpoint |
qr_code | data URL | no | Proprietary parameter. An image as data URL to present, contains the verification_url_complete encoded |
interval | integer | no | The polling interval the device should respect when waiting for user approval |
expires_in | integer | yes | The time in seconds the device_code and user_code are valid for |
Token Endpoint Request
- Method:
POST
- Content-Type:
application/x-www-form-urlencoded
- Response Type:
application/json
Request Parameters
Parameter | Value | Mandatory | Description |
---|---|---|---|
client_id | The Client ID | yes | The ID of the requesting client |
client_secret | The client secret | yes* | The secret of the client. *Mandatory if client authentication is of type secret, and the authentication is not done using basic authentication |
grant_type | urn:ietf:params:oauth:grant-type:device_code | yes | Defines the flow type: device flow |
device_code | string | yes | The device code from the device verification endpoint request |
Response
- Response Type:
application/json
Parameter | Value | Mandatory | Description |
---|---|---|---|
access_token | A newly issued access token | yes | The resulting access token for the flow |
refresh_token | A newly issued refresh token | no | Only issued if the client is configured to receive refresh tokens |
expires_in | Expiration in seconds | yes | The lifetime of the access token in seconds |
scope | Space-separated string | no | If not present, the requested scopes were issued. If present, the issued scopes may differ from the requested scopes |
token_type | Bearer or other token type | yes | Describes how the token can be used. Most commonly, bearer token usage |
If the user authorization is not complete, the response will look as follows:
Pending Response
- Response Type:
application/json
- Status Code: 400
Parameter | Value | Mandatory | Description |
---|---|---|---|
error | authorization_pending | yes | The authorization is not yet complete. Wait for interval time and try again` |
error_description | human-readable string | no | A more detailed description of the state |
Other errors in the response should cause the device to abort polling and ask the user to restart the flow.
Benefits of Device Flow
The device flow provides a secure and user-friendly method for authenticating devices with limited input capabilities. By allowing users to authorize devices through a secondary device with a full-featured browser, it enhances security and usability.

Jacob Ideskog
Identity Specialist and CTO at Curity
Join our Newsletter
Get the latest on identity management, API Security and authentication straight to your inbox.
Start Free Trial
Try the Curity Identity Server for Free. Get up and running in 10 minutes.
Start Free Trial