Skip to main content

Device Authorization Grant (TV Login)

The OAuth 2.0 Device Authorization Grant is designed for Internet-connected devices that either lack a browser to perform a user-agent-based authorization, or are input-constrained to the extent that it is impractical or very difficult for the user to input text in order to authenticate during the authorization flow. It enables OAuth clients on such devices (like smart TVs, media consoles, etc.) to obtain user authorization to access protected resources by using a user agent on a separate device (smartphone, computer). The user can open a link on their handy device in order to provide authorization on the original device. To do this, device apps use the Device Authorization Flow (known as Device Authorization Grant), in which they pass along their Client ID to initiate the authorization process and get a token.

Using this flow, the user will navigate to a login page on the TV device, which will present a screen with a QR code or URL similar to the one illustrated below:

The Flow

  1. User navigates to the sign-in page in the app.
  2. App presents a QR code/ URL to the login form.
  3. User opens to the browser using the URL, fills the form and submits.
  4. App polling the authorization server token endpoint to get user status.
  5. Once the user is authenticated via the the web browser form, the authorization server returns the token to the app.
  6. Token is stored on the TV device.


Modern Authorization providers and Identity and Access Management platforms (Auth0, Okta, Azure AD) support natively OAuth 2.0 Device Authorization Grant.

With supported platforms, you can easily integrate with Zapp by adding Zapp's TV OAuth2 Plugin.

In case your Identity management platform or Authorization server provider does not support the OAuth 2.0 Device Authorization Grant, you can build a proxy server which will cover this.

This proxy service will act as an OAuth server that implements the device code flow, proxying to a real OAuth server behind the scenes.

In order to integrate with Zapp's TV OAuth2 Plugin it is required to implement the following endpoints:

Device endpoint

When the user wants to log in, the device makes a POST request to begin the process. The POST request contains client_id (provided by your authorization service). Devices like these are considered “public clients”, so no client_secret is used in them, similar to mobile apps.

POST client_id=<CLIENT_ID>

The server should respond with the following response:

"device_code": "ff5bc299707098b5d1ab7efaffbb2f4d499f0ae951eccc4965b44129e2cdfd64", // device unique id
"user_code": "CMPN-NCEK",
"verification_uri": "",
"expires_in": 300, //in seconds
"interval": 5 // in seconds

device_code - This is a long string that the device will use to eventually exchange for an access token. verification_uri - This is the URL the user needs to enter into their handy device to start logging in / registration. user_code - This is the text the user will enter at the URL above. expires_in - The number of seconds that these values are valid. After this amount of time, the device_code and user_code will expire and the device will have to start over the process. interval - The number of seconds the device should wait between polling to see if the user has finished logging in When the login plugin is presented on the TV device it uses this endpoint to pull the information to present on the screen.

After the data is being presented, the screen starts to poll the server's Token endpoint.

Token Endpoint



While the user is busy logging in on their phone or computer, the token endpoint server should respond with the following error:

"error": "authorization_pending"

The authorization_pending error means the user isn’t finished logging in, but the code hasn’t yet expired either. The device should try this again after the specified number of seconds provided under the interval property.

Once the user finishes the login/registration process, the next time the TV device will poll the server, it should respond with the following:

"access_token": "some access token",
"expires_in": 3600,
"refresh_token": "some refresh token"

In case your OAuth2 authorization provider does not support this flow natively, you can implement a simple proxy server to connect to it.

You can use this open source as a reference.