Getting Tokens: OIDC
Introduction
There are two OIDC procedures:
- The OIDC implicit code flow gets ID tokens and optional user access tokens.
- The OIDC authorization code flow gets ID tokens and user access tokens.
See the Apps & Authentication Guide for an explanation of the different types of procedures.
OIDC implicit code flow
1) Send the user you want to authenticate to your registered redirect URI. Then, an authorization page will ask the user to sign up or log into Twitch and allow the user to choose whether to authorize your application/identity system. Use this request:
GET https://id.twitch.tv/oauth2/authorize ?client_id=<your client ID> &redirect_uri=<your registered redirect URI> &response_type=<type> &scope=<space-separated list of scopes> &claims=<JSON object specifying requested claims>
There are several required and optional query-string parameters:
Required Parameter | Type | Description |
---|---|---|
client_id | string | Your client ID. |
redirect_uri | URI | Your registered redirect URI. This must exactly match the redirect URI registered in the prior, Registration step. |
response_type | string | There are two valid values: token id_token – Return an access token and an ID token (JWT). A given user is prompted to confirm authorization only on the first request. This should be URL encoded as token+id_token or token%20id_token . id_token – Return only an ID token. For example, a client with a valid access token, who only needs added information about the user authorizing it, might specify this option. |
scope | string | Space-separated list of scopes. This must include the |
Optional Parameter | Type | Description |
---|---|---|
claims | string | JSON object encoded as a string specifying the claims to be returned in the ID token and/or the UserInfo endpoint response. |
nonce | string | OIDC opaque value to avoid CSRF attacks. (Specifically, this is used to associate the client’s authorization session with an ID token, to avoid replay attacks.) This value is echoed back in the response. We strongly recommend you use this. |
state | string | Your unique token, generated by your application. This is an OAuth 2.0 opaque value, used to avoid CSRF attacks. This value is echoed back in the response. We strongly recommend you use this. |
In our example, you request access to the user’s viewing activity (by specifying the viewing_activity_read
scope) and email verification state, and send the user to http://localhost
:
GET 'https://id.twitch.tv/oauth2/authorize?response_type=token+id_token&client_id=uo6dggojyb8d6soh92zknwmi5ej1q2&redirect_uri=http://localhost&scope=viewing_activity_read+openid&state=c3ab8aa609ea11e793ae92361f002671&claims={"id_token":{"email_verified":null}}'
2) If the user authorizes your application, the user is sent to your redirect URI, with an ID token and optionally an access token (if that was requested):
https://<your registered redirect URI>#id_token=<an id token>&access_token=<an access token>
The payload of the JWT that is returned includes several default claims about the OIDC ID token, plus any additional claims you requested:
iss
– Token issuer (Twitch)sub
– Subject or end-user identifieraud
– Audience or OAuth 2.0 client that is the intended recipient of the tokenexp
– Expiration time (note that when the JWT ID tokens expire, they cannot be refreshed)iat
– Issuance timenonce
– Value optionally specified in the request
In our example, the ID token will have an additional claim, email_verified
, because that was in the request.
The ID and access tokens are in the URL fragment, not the query string, so they will not show up in HTTP requests to your server. URI fragments can be accessed from JavaScript with document.location.hash
.
The response includes the state parameter in the URL fragment and/or the nonce
parameter in the ID token’s payload, if they were provided on your initial request.
Here is a sample response with both an ID token and access token:
https://localhost#access_token=0123456789abcdefghijABCDEFGHIJ &token_type=bearer &id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjRvaXU4In0.eyJzdWIiOiJuZnlmZSIsImF1ZCI6ImltX29pY19jbGllbnQiLCJqdGkiOiJUOU4xUklkRkVzUE45enU3ZWw2eng2IiwiaXNzIjoiaHR0cHM6XC9cL3Nzby5tZXljbG91ZC5uZXQ6OTAzMSIsImlhdCI6MTM5MzczNzA3MSwiZXhwIjoxMzkzNzM3MzcxLCJub25jZSI6ImNiYTU2NjY2LTRiMTItNDU2YS04NDA3LTNkMzAyM2ZhMTAwMiIsImF0X2hhc2giOiJrdHFvZVBhc2praVY5b2Z0X3o5NnJBIn0.g1Jc9DohWFfFG3ppWfvW16ib6YBaONC5VMs8J61i5j5QLieY-mBEeVi1D3vr5IFWCfivY4hZcHtoJHgZk1qCumkAMDymsLGX-IGA7yFU8LOjUdR4IlCPlZxZ_vhqr_0gQ9pCFKDkiOv1LVv5x3YgAdhHhpZhxK6rWxojg2RddzvZ9Xi5u2V1UZ0jukwyG2d4PRzDn7WoRNDGwYOEt4qY7lv_NO2TY2eAklP-xYBWu0b9FBElapnstqbZgAXdndNs-Wqp4gyQG5D0owLzxPErR9MnpQfgNcai-PlWI_UrvoopKNbX0ai2zfkuQ-qh6Xn8zgkiaYDHzq4gzwRfwazaqA &state=c3ab8aa609ea11e793ae92361f002671 &scope=viewing_activity_read
3) Validate the ID token. This is an important security measure to ensure the authenticity of the token and guard against any tampering.
To verify the signature of our ID tokens, we host a public JSON Web Key (JWK) here. For details on how to use our JWK in validating ID tokens, see How to validate an OpenID Connect ID token.
OIDC authorization code flow
1) Send the user you want to authenticate to your registered redirect URI. Then, an authorization page will ask the user to sign up or log into Twitch and allow the user to choose whether to authorize your application/identity system. Use this request:
GET https://id.twitch.tv/oauth2/authorize ?client_id=<your client ID> &redirect_uri=<your registered redirect URI> &response_type=code &scope=<space-separated list of scopes> &claims=<JSON object specifying requested claims>
There are several required and optional query-string parameters:
Required Parameter | Type | Description |
---|---|---|
client_id |
string | Your client ID. |
redirect_uri |
URI | Your registered redirect URI. This must exactly match the redirect URI registered in the prior, Registration step. |
response_type |
string | This must be code , causing an authorization code to be returned, which is used later in this procedure. A given user is prompted to confirm authorization only on the first request. |
scope |
string | Space-separated list of scopes. This must include the openid scope. |
Optional Parameter | Type | Description |
---|---|---|
claims |
string | JSON object encoded as a string specifying the claims to be returned in the ID token and/or the UserInfo endpoint response. |
nonce |
string | OIDC opaque value to avoid CSRF attacks. (Specifically, this is used to associate the client’s authorization session with an ID token, to avoid replay attacks.) This value is echoed back within the ID token. We strongly recommend you use this. |
state |
string | Your unique token, generated by your application. This is an OAuth 2.0 opaque value, used to avoid CSRF attacks. This value is echoed back in the response. We strongly recommend you use this. |
In our example, you request access to the user’s viewing activity (by specifying the viewing_activity_read
scope) and email verification state, and send the user to http://localhost
:
bash GET 'https://id.twitch.tv/oauth2/authorize?response_type=code&client_id=uo6dggojyb8d6soh92zknwmi5ej1q2&redirect_uri=http://localhost&scope=viewing_activity_read+openid&state=c3ab8aa609ea11e793ae92361f002671&claims={"id_token":{"email_verified":null}}'
2) If the user authorizes your application, the user is redirected to your redirect URI, with an authorization code:
https://<your registered redirect URI>/?code=<authorization code>
The OAuth 2.0 authorization code is a 30-character, randomly generated string. It is used in the next step, a request made to the token endpoint in exchange for access and ID tokens.
The response includes the state
parameter in the query string and/or the nonce
parameter in the ID token’s payload, if they were provided on your initial request.
In our example, your user gets redirected to:
http://localhost/?code=394a8bc98028f39660e53025de824134fb46313 &scope=viewing_activity_read &state=c3ab8aa609ea11e793ae92361f002671
3) On your server, get an access token and ID token by making this request:
json POST https://id.twitch.tv/oauth2/token ?client_id=<your client ID> &client_secret=<your client secret> &code=<authorization code received above> &grant_type=authorization_code &redirect_uri=<your registered redirect URI>
Here is a sample request:
POST https://id.twitch.tv/oauth2/token ?client_id=uo6dggojyb8d6soh92zknwmi5ej1q2 &client_secret=nyo51xcdrerl8z9m56w9w6wg &grant_type=authorization_code &redirect_uri=http://localhost &code=394a8bc98028f39660e53025de824134fb46313
4) We respond with a JSON-encoded access token and an ID token. The payload of the JWT that is returned includes several default claims about the OIDC ID token, plus any additional claims you requested:
iss
– Token issuer (Twitch)sub
– Subject or end-user identifieraud
– Audience or OAuth 2.0 client that is the intended recipient of the tokenexp
– Expiration time (note that when the JWT ID tokens expire, they cannot be refreshed)iat
– Issuance timenonce
– Value optionally specified in the request
In our example, the ID token will have additional claim, email_verified
, because that was in the request.
Here is a sample response:
json { "access_token": "0123456789abcdefghijABCDEFGHIJ", "refresh_token": "eyJfaWQmNzMtNGCJ9%6VFV5LNrZFUj8oU231/3Aj", "expires_in": 3600, "scope": ["viewing_activity_read"], "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxNDk0MzkxNDQiLCJ1cGRhdGVkX2F0IjoiMDAwMS0wMS0wMVQwMDowMDowMFoiLCJpc3MiOiJodHRwczovL3Bhc3Nwb3J0LnR3aXRjaC50diIsImF1ZCI6IjJrOGl6MnE0eG1scDM2MmQyaWR5YzBoNnA0MmQxZSIsImV4cCI6IjIwMTctMDUtMDVUMjI6MzI6MjcuNzk1MzQxNjI1WiIsImlhdCI6MTQ5NDAyMjY0N30=.6HkHCuwUufojZn3ogeyl8Bi0J8IyVjIzrTLLR-v-MpmP2-EYExjVT_aPjoIfuOmfK2cCDCsGSRL-p7rtFamuv3e4v--S_TkhekLioAdL-9Nm-ZnX8kdys9XYLEf8acFkQOmQ2W5DLfm68u3zAmpRMXsq_LPcsWVbPe5AGZK4Tt5mS5JIK1S8VCPTQLc7__rMI_3Hzpij09fILlbaicAKPqybLnqfMowyemcWmrecseNc_Jig_ZpGm7RqNkbxctBIBDouB_rGtH1R1CwlDs_PE5pSq4I67G6aoL0P4aUIOpFCXxLU45975ZdQDRRq3o2Lqce6cmRLOemO5JSCyTGZhQ==", "token_type": "bearer" }
5) Validate the ID token. This is an important security measure to ensure the authenticity of the token and guard against any tampering.
To verify the signature of our ID tokens, we host a public JSON Web Key (JWK) here. For details on how to use our JWK in validating ID tokens, see How to validate an OpenID Connect ID token.
Claims
Each claim describes a piece of data you want to get about the user authorizing your application. In the claims
parameter of your OIDC request, you can choose to include any, all, or none of the claims. If you choose to omit any specific claims, we include several claims by default.
Claims are requested by passing a claims
parameter in the authorization request. These requested claims can be retrieved in the ID token itself or through the UserInfo endpoint. How data is returned for each claim varies, depending on the format of the claims
parameter in the request.
The claims
parameter is a JSON object with two fields: id_token
and userinfo
. You may specify claims in both fields, and there is no requirement on presence or uniqueness of the claims in either field. For example, to include a user’s email and email verification state in the ID token and a profile image through the UserInfo endpoint, the claims
parameter would be:
{ "id_token": { "email": null, "email_verified": null }, "userinfo": { "picture": null } }
In the request, the claims
parameter would be:
claims={"id_token":{"email":null,"email_verified":null},"userinfo":{"picture":null}}
The email
and email_verified
claims will be included in the ID token that is returned. The picture
claim will be returned when you call the UserInfo endpoint with the OAuth token returned in the authorization request (assuming you requested an OAuth token in the flow with either the implicit or authorization code flow).
You can request the following claims:
Claim | Data |
---|---|
email | Email address of the authorizing user. |
| Email verification state of the authorizing user. |
picture | Profile image URL of the authorizing user. |
preferred_username | Display name of the authorizing user. |
updated_at | Date of the last update to the authorizing user’s profile. |
Note: The email
and email_verified
claims will soon be gated by the user:read:email
scope that must be included on the authorization request.
The following claims are included by default in both the ID token and the UserInfo endpoint:
Default Claim | Data |
---|---|
| Audience: client ID of the application requesting a user’s authorization. |
azp | Authorized party: client ID of the application which is being authorized. Currently the same as aud . |
exp | Expiration time of the token. This is in UNIX/Epoch format. |
iat | Time when the token was issued. This is in UNIX/Epoch format. |
iss | Issuer of the token. |
sub | User ID of the authorizing user. |
UserInfo endpoint
The UserInfo
endpoint allows you to fetch claims originally provided in the authorization request outside of the ID token. Note that this endpoint is available only if you receive an OAuth token on behalf of the authorizing user. If your authorization request specifies only the id_token
response type, you will not have an OAuth token to call this endpoint.
GET 'https://id.twitch.tv/oauth2/userinfo' -H "Authorization: Bearer <OAuth token>"
The response is the requested claims (along with the default claims), in JSON form:
{ "aud": "<your client ID>", "exp": 1542051527, "iat": 1542050627, "iss": "https://id.twitch.tv/oauth2", "sub": "<authorizing user ID>", "azp": "<your client ID>", "picture": "<authorizing user profile image>" }