Contents

Getting Tokens: OIDC

Introduction

There are two OIDC procedures:

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 ParameterTypeDescription
client_idstringYour client ID.
redirect_uriURIYour registered redirect URI. This must exactly match the redirect URI registered in the prior, Registration step.
response_typestringThere 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.
scopestring

Space-separated list of scopes. This must include the openid scope.

Optional ParameterTypeDescription
claimsstring

JSON object encoded as a string specifying the claims to be returned in the ID token and/or the UserInfo endpoint response.

noncestringOIDC 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.
statestringYour 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:

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:

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:

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:

In our example, the ID token will have additional claim, email_verified, because that was in the request.

Here is a sample response:

{
   "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 you view the data 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 these claims:

ClaimData
emailEmail address of the authorizing user.

email_verified

Email verification state of the authorizing user.
pictureProfile image URL of the authorizing user.
preferred_usernameDisplay name of the authorizing user.
updated_atDate of the last update to the authorizing user’s profile.

These claims are included by default in both the ID token and the UserInfo endpoint:

Default ClaimData

aud

Audience: client ID of the application requesting a user’s authorization.

azpAuthorized party: client ID of the application which is being authorized. Currently the same as aud.
expExpiration time of the token. This is in UNIX/Epoch format.
iatTime when the token was issued. This is in UNIX/Epoch format.
issIssuer of the token.
subUser 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>"
}