|  | 
|  | 1 | +--- | 
|  | 2 | +id: device-authorization | 
|  | 3 | +title: Device Authorization | 
|  | 4 | +sidebar_label: Device authorization flow | 
|  | 5 | +--- | 
|  | 6 | + | 
|  | 7 | +The OAuth 2.0 Device Authorization Grant -also known as Device Flow- is OAuth 2.0 extension that enables devices with no browser | 
|  | 8 | +or limited input capability to obtain an access token. It enables users to authotize devices with limited input capabilities, such | 
|  | 9 | +as smart TVs, gaming consoles, or IoT devices, by delegating the authentication process to another device with a full browser such | 
|  | 10 | +as a phone or computer. | 
|  | 11 | + | 
|  | 12 | +This document provides an overview of the Device Authorization Grant, a step-by-step example of its implementation, configuration | 
|  | 13 | +options, and guidance on creating custom user interfaces for the verification screen. | 
|  | 14 | + | 
|  | 15 | +## Overview of the flow | 
|  | 16 | + | 
|  | 17 | +Here is the high-level overview for the Device Authorization Flow: | 
|  | 18 | + | 
|  | 19 | +1. The device requests to be authorized from the Authorization Server. | 
|  | 20 | +1. The user is instructed to visit a URL on a different device and is given a user code. | 
|  | 21 | +1. On a different device the user visits the URL, provides the user code, logs in and grants access to the device. | 
|  | 22 | +1. The device polls the Authorization Server. Once the user authenticates and grants access, an access token is returned that can | 
|  | 23 | +   be used to access the protected resource. | 
|  | 24 | + | 
|  | 25 | +### Device requests authorization | 
|  | 26 | + | 
|  | 27 | +The user tries to log in through the limited input device. The device sends a POST request to the Authorization Server to initiate | 
|  | 28 | +the flow with the following parameters: | 
|  | 29 | + | 
|  | 30 | +- `client_id`: The ID of the client that's making the request. | 
|  | 31 | +- `scope` (optional): The scope of the access request, which specifies what resources the requesting application can access. | 
|  | 32 | + | 
|  | 33 | +The Authorization Server responds with the following information: | 
|  | 34 | + | 
|  | 35 | +- `device_code`: A unique code to identify the authorization request. | 
|  | 36 | +- `user_code`: A code the user will enter at the verification URL. | 
|  | 37 | +- `verification_uri`: The URL where the user can authorize the device. | 
|  | 38 | +- `verification_uri_complete`: The URL where the user can authorize the device, with the user_code already filled in. | 
|  | 39 | +- `expires_in`: The lifespan of the device code (in seconds). | 
|  | 40 | +- `interval`: The polling interval (in seconds) for the client to check if the user has authorized the device. | 
|  | 41 | + | 
|  | 42 | +### Display user code and verification URI | 
|  | 43 | + | 
|  | 44 | +The device shows the user the `user_code` and `verification_uri` it received from the Authorization Server. | 
|  | 45 | + | 
|  | 46 | +The user visits the provided URI on a separate device, such as a phone, and enters the code. | 
|  | 47 | + | 
|  | 48 | +### User grants permission | 
|  | 49 | + | 
|  | 50 | +Once the user enters the code, they're prompted to log in, if not already authenticated, and grant or deny permission to the | 
|  | 51 | +client. After granting permission, the user is redirected to a page confirming successful login. | 
|  | 52 | + | 
|  | 53 | +### Device polls for the access token | 
|  | 54 | + | 
|  | 55 | +While the user is authorizing the device, the device polls the `token` endpoint of the Authorization Server to check whether the | 
|  | 56 | +user has completed the authorization process, by making a POST request with the following parameters: | 
|  | 57 | + | 
|  | 58 | +- `client_id`: The ID of the client that's making the request. | 
|  | 59 | +- `device_code`: The device code received from the device authorization request. | 
|  | 60 | +- `grant_type`: This should always be `urn:ietf:params:oauth:grant-type:device_code`. | 
|  | 61 | + | 
|  | 62 | +After the user grants permission, the Authorization Server will respond with an access token. | 
|  | 63 | + | 
|  | 64 | +## Configuration options | 
|  | 65 | + | 
|  | 66 | +### Configuring the user interface | 
|  | 67 | + | 
|  | 68 | +To enable and configure the Device Authorization Grant in Ory Hydra, adjust the following settings in your configuration file: | 
|  | 69 | + | 
|  | 70 | +``` | 
|  | 71 | +urls: | 
|  | 72 | +  device: | 
|  | 73 | +    verification: http://path/to/device/verification/ui | 
|  | 74 | +    success: http://path/to/device/success | 
|  | 75 | +``` | 
|  | 76 | + | 
|  | 77 | +### Configuring user code entropy | 
|  | 78 | + | 
|  | 79 | +Depending on your security needs and your traffic load, you may wish to enhance your `user_code` entropy. The Ory Hydra | 
|  | 80 | +`oauth2.device_authorization.user_code_entropy` configuration supports 3 values: | 
|  | 81 | + | 
|  | 82 | +- `high`: `user_code` is 8 characters long and consists of alphanumeric characters, excluding some ambiguous symbols | 
|  | 83 | +- `medium`: `user_code` is 8 characters long and consists of upper case letter | 
|  | 84 | +- `low`: `user_code` is 9 characters long and consists of numbers | 
|  | 85 | + | 
|  | 86 | +Keep in mind that higher entropy may make it harder for the user to enter the user code. | 
|  | 87 | + | 
|  | 88 | +## Device verification user interface implementation | 
|  | 89 | + | 
|  | 90 | +Here is a sample implementation for a device verification UI : | 
|  | 91 | + | 
|  | 92 | +```js | 
|  | 93 | +import { Configuration, OAuth2Api } from "@ory/client" | 
|  | 94 | +import { Request, Response } from "express" | 
|  | 95 | + | 
|  | 96 | +const ory = new OAuth2Api( | 
|  | 97 | +  new Configuration({ | 
|  | 98 | +    basePath: `https://${process.env.ORY_PROJECT_SLUG}.projects.oryapis.com`, | 
|  | 99 | +    accessToken: process.env.ORY_API_KEY, | 
|  | 100 | +  }), | 
|  | 101 | +) | 
|  | 102 | + | 
|  | 103 | +// Please note that this is an example implementation. | 
|  | 104 | +// In a production app, please add proper error handling. | 
|  | 105 | +export async function handleLogin(request: Request, response: Response) { | 
|  | 106 | +  const challenge = request.query.device_challenge.toString() | 
|  | 107 | +  const userCode = request.query.user_code.toString() | 
|  | 108 | + | 
|  | 109 | +  // Show the login form if the form was not submitted. | 
|  | 110 | +  if (request.method === "GET") { | 
|  | 111 | +    response.render("device", { | 
|  | 112 | +      challenge, | 
|  | 113 | +      userCode, | 
|  | 114 | +    }) | 
|  | 115 | +    return | 
|  | 116 | +  } | 
|  | 117 | + | 
|  | 118 | +  // User was authenticated successfully, | 
|  | 119 | +  return await ory | 
|  | 120 | +    .acceptUserCodeRequest({ | 
|  | 121 | +      deviceChallenge: challenge, | 
|  | 122 | +      acceptDeviceUserCodeRequest: { | 
|  | 123 | +        user_code: userCode, | 
|  | 124 | +      }, | 
|  | 125 | +    }) | 
|  | 126 | +    .then(({ redirect_to }) => { | 
|  | 127 | +      response.redirect(String(redirect_to)) | 
|  | 128 | +    }) | 
|  | 129 | +} | 
|  | 130 | +``` | 
0 commit comments