Language not available Language not available Language not available

This post is not available in your language. Here are some other options:

Twitch Authentication: Understanding Which Protocol and Flow is Right For You

Nov 6 2019

One of the most common hurdles when first developing a new integration or Extension with Twitch is determining the authentication method that best fits your needs. This decision can be confusing, especially when you’re new to authenticating to REST APIs, but this guide will cover how to make an informed decision on the protocol, necessary type of token, and the appropriate way to use the protocol.

Twitch offers two protocols, OAuth and OIDC, to connect and obtain a token using your choice of flow. A “flow” simply refers to the way that your application interacts with Twitch in exchange for a token, and how that token is returned.

Additionally, along with the two protocol choices, you have an important decision to make around the type of token that you need; there are three different kinds of tokens available, each with different purposes.

These decisions can vary based on a number of factors, such as the type of integration being built, how your application is architected, and your experience level with using authentication protocols.

In short, there’s a simple chart that displays the different types of tokens and infrastructure to help with your decision-making process. Please note that this isn’t definitive; your situation can vary and you should choose the option that best suits your needs.

  Have a Backend No Backend /SPA Server-to-Server (no frontend)
ID Token OIDC Auth Code OIDC Implicit -
User Access Token OAuth/OIDC Auth Code OAuth/OIDC Implicit -
App Access Token OAuth Client Credential (on backend) - OAuth Client Credentials

Protocols

As noted previously, there are two protocols to choose from when authenticating users in your application — OAuth 2.0 and OIDC. These two protocols are functionally very similar as OIDC was built on top of the OAuth 2.0 specification, but there are reasons to pick one over the other.

OAuth 2.0

The first protocol we’ll cover is OAuth 2.0 (herein referred to as OAuth), which is one of the most common ways to authorize with the Twitch platform. The wide adoption of OAuth among many organizations leans itself into large numbers of libraries available to the public for nearly all programming languages, meaning that it is quick and easy to build authorization in your application with minimal custom work needed. OAuth can provide a user access token or app access token. A user access token (oftentimes called “access token”) allows your application to perform actions on behalf of the authenticated user given a set of scopes (permissions). App access tokens, on the other hand, are only used for server-to-server calls and do not provide access to some protected API endpoints.

User access tokens and app access tokens are used to authenticate calls against Twitch’s APIs.

One major issue with OAuth, however, is that it is not an authentication protocol. OAuth itself does not tell who the user is, and instead provides a set of delegated permissions that allow access to protected resources through the provided access token. This authorizes the token to access material, but does not authenticate users.

You can get details about the user who authorized the token via Twitch API’s Get User endpoint, but calling this endpoint just to get user identity would be a misuse of OAuth as it would simply tell you the owner of the token, but not that they authenticated into your application.

The difference here mostly deals with security principles. A token is not proof of a user authentication, just like a front door key is not a proof of house ownership. The token only proves that the user has authorized your application to act on their behalf, and this is one of the primary reasons that we suggest using the second protocol described below.

OpenID Connect

OpenID Connect (OIDC) is built on top of OAuth and standardizes a number of things that the OAuth specification leaves up to choice. In addition, OIDC provides authentication in addition to authorization. As OIDC is layered on top of OAuth, many things remain the same making it easy to learn if you are already familiar with OAuth.

One of the key differences with OIDC is that it can return an ID Token, which is a JSON Web Token (JWT) with information about the authenticated user. This token can contain basic information about the user via claims, or details about the user. Claims can include (but not limited to) the username, email, and profile image. This information is available without an additional API call and provides a quick resource for that information. This authenticates the user to ensure the user is the one accessing the material.

An example JWT looks like:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjEifQ.eyJhdWQiOiJhOGF2NHo3MGY1M2QyMnNwZXBlemJkaWx5Y29yaHQiLCJleHAiOjE1NTk2NzY2NDEsImlhdCI6MTU1OTY3NTc0MSwiaXNzIjoiaHR0cHM6Ly9pZC50d2l0Y2gudHYvb2F1dGgyIiwic3ViIjoiNDQ2MzU1OTYiLCJwaWN0dXJlIjoiaHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy8zNzVlZTZmZC04ZGNkLTQ3ZjEtOTNkYi04MTY2NzgyODhlMTMtcHJvZmlsZV9pbWFnZS0xNTB4MTUwLnBuZyIsInByZWZlcnJlZF91c2VybmFtZSI6IkNvbmNyZXRlRW50cmVlIn0.xz44-jsojGL188TkO5TqqEVusAnCEFWUXdkX5awV-0m5FFTHqEfZOTHxUMV3UCfmDGaz76g0kVm0NErYT4GRZjYmeahIYOWFQhQ0tdf31JGflrh3IXCjHAEnAcVHiHLQirrK9gC2zuqIbW3383lLmiFbakG1KdginYScWjUTHF3RPyeQsWjQI8iscRr_i9ogmRnHfq1bj3sS0DBQiJ1OTmUwBhXFXI9dWZGskvCXDAQ2m06ulB7lYgkl_yaqYaXOfnhcrvIrfcwSTqByPJP3bpUwFUsDpePhShFuogxEpzF1hWSXb1x819uldtF0PQfBhAtIs28f5DrSDUWNb5IChQ

When decoded (using https://jwt.io), the above JWT is expanded to be:

{
  "aud": "a8av4z70f53d22spepezbdilycorht",
  "exp": 1559676641,
  "iat": 1559675741,
  "iss": "https://id.twitch.tv/oauth2",
  "sub": "44635596",
  "picture": "https://static-cdn.jtvnw.net/jtv_user_pictures/375ee6fd-8dcd-47f1-93db-816678288e13-profile_image-150x150.png",
  "preferred_username": "ConcreteEntree"
}

This information can also be used for presentational purposes, so, for instance, a React application could store the JWT in the state and reference the username as part of the page’s header instead of storing that somewhere in a database that needs to be fetched on login; that data is also updated with each token refresh, meaning the data is up to date.

It is important to note that the ID Token is not used for making API requests and is simply proof of authentication as well as user identity.

OIDC can also return a standard user access token in addition to the ID Token, allowing you both to act on a user’s behalf and to know who the user is.

The major caveat with OIDC is that it does not support the return of app access tokens, meaning that for server-to-server communications OAuth is your only option. That said, we do recommend using OIDC whenever possible in all other circumstances.

Flows

For both OAuth and OIDC, they both support two different flows, or methods of obtaining tokens. They are the Authorization Code flow and Implicit flow.

Both flows differ in a few key ways. Authorization Code should be used where there is a server making the calls to get the token and to access protected API endpoints using this token. There are additional handshakes that provide the necessary information, meaning that the user is never given access to their actual access token (unless you send it to the frontend), making it much more secure. Additionally, this flow also returns a refresh token, meaning your users won’t have to reauthorize your application in the future. These refresh tokens are used by your application to give a new access token for the user with a new expiration date.

Implicit Code is used when the client (user agent) will be making the calls. This is most common with Single Page Apps (SPA) that use frameworks such as React or Vue. The user authenticates, and the browser is getting and storing the token locally to make additional calls on behalf of the user, or that the SPA doesn’t have a backend to store the user data. Although SPA architecture involves a web service that stores the code, this service never gets access to user’s access token (unless the client sends it to the backend). This flow does not return a refresh token, so you’ll need the users to reauthorize the application when the token expires.

Lastly, there’s also the Client Credentials flow which allows you to obtain an app access token. This flow is only available via the OAuth protocol and is the only way to get app access tokens. These tokens, as noted above, are unable to use endpoints that access protected data for a given user (e.g. a user’s email in the GET /users endpoint) due to the lack of user principle and are meant for server-to-server calls only. This flow does not return a refresh token.

Authorization Code

As noted above, the Authorization Code flow requires a few additional calls compared to the other flows, however ends up in a more secure application due to the non-transfer of access token to the browser during the authorization process.

The process for Authorization Code is:

  1. Your application redirects the user to the Twitch login endpoint
  2. User logs in and authorizes the application with the requested scopes
  3. Once successfully authorized, Twitch redirects back to your application and includes a code in the query parameters
  4. The code is then exchanged using the backend server for your desired tokens using a special endpoint

This process allows you to store the tokens securely and discreetly. While there are more steps than the Implicit flow, this is the preferred method by Twitch.

Implicit Code

The other user-facing flow is the Implicit flow. This flow focuses on transmitting the access token across as securely as possible, however the access token is exposed to the end-user regardless. Because of this, Implicit flows don’t support refresh tokens and requires that users re-authenticate each time to get a valid user token.

The way that this is done through:

  1. The user is redirected to the Twitch login (using popup or browser redirect)
  2. The user then authorizes the application
  3. The user then is redirected by Twitch to the Redirect URI (as configured by the integration) with the tokens in the URL fragment.
  4. The URL would look like: https://yoururlhere/index.html#access_token=token…

The token in this case is not in the request query, as request queries are transmitted to the backend server (and any other servers that may come in the middle). Instead, it uses the URL fragment, which is not visible to the backend servers and is therefore slightly more secure. The URL fragment is accessible by client-side JavaScript, allowing you to pull it out of the URL and store for later.

Client Credentials

Lastly, the Client Credentials flow is intended when you need to make calls from server to server. This token can’t add any additional scopes, since there isn’t a user to bind the token to; instead, these are meant for backend tasks that are not specific to any user. It could be tasks that involve application-level analytics or that need higher rate limits.

As noted in the chart, this flow is only able to be done using OAuth, not OIDC. As such, keep that in mind when choosing this flow.

The flow is fairly simple; the backend server makes a request to Twitch for a token and is given one in return. The response format is identical to the authorization code response, so you are able to refresh the token in the same way.

Unlike the other flows, however, since this only generates an app access token, it cannot be assigned to a user, thus you cannot assign scopes to this token. Using this type of token is commonly used to increase the rate limit of your calls to make sure you’re not making unauthenticated requests.

Summary

Determining what technology to use to have users authorize your application is a fairly important decision you’ll make early on. Due to the number of options available, it can be overwhelming when first starting your project. Simply put, however, for most use cases, if you can use OIDC, you should do so. Given that OIDC is built on top of OAuth, the authorization flow remains the same for the end-user, and you gain additional functionality while also retaining all of the ease of use of OAuth without much more additional complexity.

In other news