Device Flow
The Device Flow is an OAuth 2.0 extension that enables devices with no browser or limited input capability to obtain an access token. This is commonly seen on Smart TV apps, or devices like hardware encoders that can stream video to a YouTube channel.
The device flow illustrated in Figure includes the following steps:
(A) The client requests access from the authorization server and includes its client identifier in the request.
(B) The authorization server issues a verification code, an end-user code, and provides the end-user verification URI.
(C) The client instructs the end user to use its user agent (elsewhere) and visit the provided end-user verification URI. The client provides the user with the end-user code to enter in order to grant access.
(D) The authorization server authenticates the end user (via the user agent) and prompts the user to grant the client's access request. If the user agrees to the client's access request, the user enters the user code provided by the client. The authorization server validates the user code provided by the user.
(E) While the end user authorizes (or denies) the client's request (step D), the client repeatedly polls the authorization server to find out if the user completed the user authorization step. The client includes the verification code and its client identifier.
(F) Assuming the end user granted access, the authorization server validates the verification code provided by the client and responds back with the access token.
Authorization Request:
First, the client makes a request to the authorization server to request the device code.
https:///authz-srv/device/authz?client_id=ddadc5c4-ad3b-46fc-9169-a27a0673386&scope=openid profile email roles groups&nonce=test
Example URL
GET /authz-srv/device/authz HTTP/1.1
client_id=xxxxxxxxxx
scope=openid profile …
nonce=test
Note that some authorization servers will allow the device to specify a scope in this request, which will be shown to the user later the authorization interface.
The authorization server responds with a JSON payload containing the device code, the code the user will enter, the URL the user should visit, and a polling interval.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"device_code": "NGU5OWFiNjQ5YmQwNGY3YTdmZTEyNzQ3YzQ1YSA",
"user_code": "BDWP-HQPK",
"verification_uri": "https://authorization-server.com/device",
"interval": 5,
"expires_in": 1800
}
The device shows the verification_uri and user_code to the user on its display, directing the user to enter the code at that URL.
Token Request:
While the device is waiting for the user to complete the authorization flow on their own computer or phone, the device meanwhile begins polling the token endpoint to request an access token.
The device makes a POST request with the device_code at the rate specified by interval. The device should continue requesting an access token until a response other than authorization_pending is returned, either the user grants or denies the request or the device code expires.
Example URL
POST /token-srv/token HTTP/1.1 Host: grant_type=urn:ietf:params:oauth:grant-type:device_code client_id=xxxxxxxxxx device_code: ef6c3055-eb6b-42cc-9330-7cd1d2ba5dd1
The authorization server will reply with either an error or an access token. The Device Flow spec defines two additional error codes beyond what is defined in OAuth 2.0 core, authorization_pending and slow_down
If the device is polling too frequently, the authorization server will return the slow_down error.
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "slow_down"
}
If the user has not either allowed or denied the request yet, the authorization server will return the authorization_pending error.
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "authorization_pending"
}
If the user denies the request, the authorization server will return the access_denied error.
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
"error": "access_denied"
}
Finally, if the user allows the request, then the authorization server issues an access token like normal and returns the standard access token response.
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "AYjcyMzY3ZDhiNmJkNTY",
"refresh_token": "RjY2NjM5NzA2OWJjuE7c",
"token_type": "bearer",
"expires": 3600
}