Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The OAuth 2.0 “Device Flow” extension enables OAuth on devices that have an Internet connection but don’t have a browser or an easy way to enter text.
This flow is seen on devices such as smart TVs, media consoles, picture frames, printers, or hardware video encoders. In this flow, the device instructs the user to open a URL on a secondary device such as a smartphone or computer in order to complete the authorization. There is no communication channel required between the user’s two devices.
First, the client makes a request to the authorization server to request the device code.
POST
http://app.com/device/code
The client makes a request to the authorization server to request the device code.
Name | Type | Description |
---|---|---|
Note that some authorization servers will allow the device to specify a scope in this request, which will be shown to the user later on the authorization interface.
After validating the client ID and scopes, the authorization server returns the response with the verification URL, device code, and user code. There are a few optional parameters that the authorization server can return in addition to the example given above.
device_code
– Required, the verification code generated by the authorization server.
user_code
– Required, the code the user will enter on the device screen should be relatively short. Typically 6-8 numbers and letters are used.
verification_uri
– Required, the URL on the authorization server that the user should visit to begin authorization. The user is expected to hand-enter this URL on their computer or mobile phone.
expires_in
– Optional, the lifetime in seconds of the device code and user code.
interval
– Optional, the minimum amount of time in seconds that the client should wait between polling requests to the token endpoint.
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.
Visiting that URL after you’ve signed in to your account shows an interface that prompts you to enter the code that’s displayed on the device.
Meanwhile, the client should attempt to acquire an access token every few seconds (at a rate specified by interval
) by POSTing to the access token endpoint on the authorization server.
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.
POST
https://app.com/device/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.
Name | Type | Description |
---|---|---|
client_id*
String
the client identifier
scope
String
Define the scopes the application has access to
grant_type*
String
The Device Code grant type value is urn:ietf:params:oauth:grant-type:device_code
client_id*
String
The client id for which the device code was created
code*
String
The value of code
should be the device_code
from the JSON response in the previous request.
Self-encoded tokens provide a way to avoid storing tokens in a database by encoding all of the necessary information in the token string itself. The main benefit of this is that API servers are able to verify access tokens without doing a database lookup on every API request, making the API much more easily scalable.
The benefit of OAuth 2.0 Bearer Tokens is that applications don’t need to be aware of how you’ve decided to implement access tokens in your service. This means it’s possible to change your implementation later without affecting clients.
A common technique for this is using the JSON Web Signature (JWS) standard to handle encoding, decoding and verification of tokens. The JSON Web Token (JWT) specification defines some terms you can use in the JWS, as well as defines some timestamp terms to determine whether a token is valid. We’ll use a JWT library in this example, since it provides built-in handling of expiration.
Access tokens eventually expire; however some grants respond with a refresh token which enables the client to get a new access token without requiring the user to be redirected.
eWhen you initially received the access token, it may have included a refresh token as well as an expiration time like in the example below.
The presence of the refresh token means that the access token will expire and you’ll be able to get a new one without the user’s interaction.
The “expires” value is the number of seconds that the access token will be valid. It’s up to the service you’re using to decide how long access tokens will be valid, and may depend on the application or the organization’s own policies. You can use this to preemptively refresh your access tokens instead of waiting for a request with an expired token to fail.
If you make an API request and the token has expired already, you’ll get back a response indicating as such. You can check for this specific error message, and then refresh the token and try the request again.
If you’re using a JSON-based API, then it will likely return a JSON error response with the invalid_token error. In any case, the WWW-Authenticate
header will also have the invalid_token error.
When your code recognizes this specific error, it can then make a request to the token endpoint using the refresh token it previously received, and will get back a new access token it can use to retry the original request.
To use the refresh token, make a POST request to the service’s token endpoint with grant_type=refresh_token
, and include the refresh token as well as the client credentials.
POST
https::/app.com/token
The refresh token, make a POST request to the service’s token endpoint with grant_type=refresh_token
, and include the refresh token as well as the client credentials.
A grant is a method of acquiring an access token. Deciding which grants to implement depends on the type of client the end-user will be using, and the experience you want for your users.
Dive into the specifics of each OAuth 2 Flow implementation
If the request for an access token is valid, the authorization server needs to generate an access token (and optional refresh token) and return these to the client, typically along with some additional properties about the authorization.
For example, a successful token response may look like the following:
The format for OAuth 2.0 Bearer tokens is actually described in a separate spec, RFC 6750. There is no defined structure for the token required by the spec, so you can generate a string and implement tokens however you want. The valid characters in a bearer token are alphanumeric, and the following punctuation characters:
The simplest of all of the OAuth 2.0 grants, this grant is suitable for machine-to-machine authentication where a specific user’s permission to access data is not required.
The Client Credentials grant type is used by clients to obtain an access token outside of the context of a user. This is typically used by clients to access resources about themselves rather than to access a user's resources.
The following is an example authorization code grant the service would receive.
POST
https://app.com/token
In some cases, applications may need an access token to act on behalf of themselves rather than a user. For example, the service may provide a way for the application to update their own information such as their website URL or icon, or they may wish to get statistics about the users of the app. In this case, applications need a way to get an access token for their own account, outside the context of any specific user. OAuth provides the client_credentials
grant type for this purpose.
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
The authorization code grant should be very familiar if you’ve ever signed into an application using your Facebook or Google account.
The authorization code grant is used when an application exchanges an authorization code for an access token. After the user returns to the application via the redirect URL, the application will get the authorization code from the URL and use it to request an access token. This request will be made to the token endpoint.
The client will redirect the user to the authorization server with the following parameters in the query string:
GET
https://authorization-server.com/authorize
The client will redirect the user to the authorization server with the following parameters in the query string:
Name | Type | Description |
---|---|---|
You should first compare this state value to ensure it matches the one you started with. You can typically store the state value in a cookie or session, and compare it when the user comes back. This helps ensure your redirection endpoint isn't able to be tricked into attempting to exchange arbitrary authorization codes.
The parameters will be validated by the authorization server.
The user will then be asked to sign in to the authorization server and approve the client.
The user sees the authorization prompt
If the user approves the client they will be redirected from the authorization server back to the client (specifically to the redirect URI) with the following parameters in the query string:
code
with the authorization code
state
with the state parameter sent in the original request. You should compare this value with the value stored in the user’s session to ensure the authorization code obtained is in response to requests made by this client rather than another client application.
The Proof Key for Code Exchange (PKCE, pronounced pixie) extension describes a technique for public clients to mitigate the threat of having the authorization code intercepted. The technique involves the client first creating a secret, and then using that secret again when exchanging the authorization code for an access token. This way if the code is intercepted, it will not be useful since the token request relies on the initial secret.
Once the app has generated the code verifier, it uses that to create the code challenge. For devices that can perform a SHA256 hash, the code challenge is a BASE64-URL-encoded string of the SHA256 hash of the code verifier. Clients that do not have the ability to perform a SHA256 hash are permitted to use the plain code verifier string as the challenge.
Now that the client has a code challenge string, it includes that and a parameter that indicates which method was used to generate the challenge (plain or S256) along with the standard parameters of the authorization request. This means a complete authorization request will include the following parameters.
The PKCE extension does not add any new responses, so clients can always use the PKCE extension even if an authorization server does not support it.
Exchange the authorization code for an access token
To exchange the authorization code for an access token, the app makes a POST request to the service’s token endpoint. The request will have the following parameters.
POST
https://my-auth-server.com/token
The server exchanges the authorization code for an access token by making a POST request to the token endpoint.
OAuth Security
Up until 2019, the OAuth 2.0 spec only recommended using the PKCE extension for mobile and JavaScript apps. The latest OAuth Security BCP now recommends using PKCE also for server-side apps, as it provides some additional benefits there as well. It is likely to take some time before common OAuth services adapt to this new recommendation, but if you’re building a server from scratch you should definitely support PKCE for all types of clients.
The implicit grant is similar to the authorization code grant with two distinct differences.
It is intended to be used for user-agent-based clients (e.g. single page web apps) that can’t keep a client secret because all of the application code and storage are easily accessible.
Secondly, instead of the authorization server returning an authorization code that is exchanged for an access token, the authorization server returns an access token.
The client will redirect the user to the authorization server with the following parameters in the query string:
response_type
with the value token
client_id
with the client identifier
redirect_uri
with the client redirect URI. This parameter is optional, but if not sent the user will be redirected to a pre-registered redirect URI.
scope
a space delimited list of scopes
state
with a token. This parameter is optional but highly recommended. You should store the value of the CSRF token in the user’s session to be validated when they return.
All of these parameters will be validated by the authorization server.
The user will then be asked to sign in to the authorization server and approve the client.
If the user approves the client they will be redirected back to the authorization server with the following parameters in the query string
The Password grant is used when the application exchanges the user’s username and password for an access token.
This is exactly the thing OAuth was created to prevent in the first place, so you should never allow third-party apps to use this grant.
A common use for this grant type is to enable password logins for your service’s own apps. Users won’t be surprised to log in to the service’s website or native application using their username and password, but third-party apps should never be allowed to ask the user for their password.
The following is an example password grant the service would receive.
See for details on the parameters to return when generating an access token or responding to errors.
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
-._~+/
Authorization
String
The client needs to authenticate themselves for this request. Typically the service will allow either additional request parameters client_id
and client_secret
, or accept the client ID and secret in the HTTP Basic auth header.
grant_type*
String
A Parameter must be set to clienst_credentials
.
scope
String
The service supports different scopes for the client credentials grant. In practice, not many services actually support this.
Authorization*
String
The client needs to authenticate themselves for this request. Typically the service will allow either additional request parameters client_id
and client_secret
, or accept the client ID and secret in the HTTP Basic auth header.
grant_type*
String
Must be set to refresh_token
refresh_token*
String
The curent refresh token
response_type*
String
Indicates that your server expects to receive an authorization code. Must be code
client_id*
String
The client ID you received when you first registered the application
redirect_uri*
String
Indicates the URI to return the user to after authorization is complete
scope*
String
One or more scope values indicating which parts of the user's account you wish to access
state
String
with a CSRF token. This parameter is optional but highly recommended.
Authorization*
String
Contains the word Basic, followed by a space and a base64-encoded(non-encrypted) string with the client id and client secret
grant_type*
String
The grant type for this flow is authorization_code
redirect_uri*
String
Must be identical to the redirect URI provided in the original link
code*
String
The authorization code from the query string
code_verifier
String
PCKE Extension - the code verifier for the PKCE request, that the app originally generated before the authorization request.