TOP

このエントリーをはてなブックマークに追加

OAuth2.0の認証フロー


はじめに

このページは、OAuth2.0の認証フローについて説明するページです。
机上の理論だけだとなかなか理解が深まらないと思うので、OAuth2.0に準拠しているTwitchの認証フローを追いながら実際にトークンを発行し、OAuth2.0の認証フローについて理解を深めていきます。
発行されたトークンをTwitchでどう使うのかについてはNode.js × Twitchを参照してください。



トークンの発行

Client ID と Client Secret が発行されたらトークンを発行できるようになります。
Twitchのトークンには App access token と User access token の2種類があり、それぞれ用途は以下の通り。

トークンの種類用途
User access token User access tokenは、リソースオーナー(※)の承認が必要なAPIを発行する場合に使用します。
Twitchのスコープ一覧に記載されているスコープを指定して、アプリケーションにアクセスを許可するリソースの範囲を指定します。
例えば以下に示すようなPoll(投票)に関するAPIを発行する場合、 channel:manage:polls スコープを指定してUser access tokenを発行する必要があります。
リンク先を見れば、channel:manage:polls スコープを含むUser access tokenが必要なことがわかります。
App access token App access tokenは、以下のような場合に使用します。
  • リソースオーナーの承認が不要な機能を利用する場合
    例えばGet Videos APIは指定したIDに紐づく情報を、リソースオーナーの承認無しで取得することができる。
    App access tokenが使用できるAPIであれば、自分の情報であろうが他人の情報であろうが取得可能だということです。
    • App access tokenを受け入れる殆どのAPIはUser access token も使用できるため、User access tokensを既に取得している場合はApp access tokenを取得する必要はない。
  • Webhookを使用してイベントを受信する場合
    • Webhookを使用してイベントの通知を受信する場合、サブスクリプションの登録リクエストを行う必要があり、その際にはApp access tokenを使用します。
      User access tokenを使用すると、リクエストは失敗します。
    • イベントの種類によってはリソースオーナーの承認が必要なものもある。channel.subscribe イベントはその一つです。
      channel.subscribe イベントを受信するには、まずリソースオーナーの承認を得るため、channel:read:subscriptions スコープを含むUser access tokenを取得します。
      その上で、App access tokenを使用してサブスクリプションの登録リクエストを行います。
リソースオーナーとは一般的に、『アカウントを持つユーザー本人』を指します。
OAuth 2.0認可フレームワークにおいて、保護されたデータやサービス(リソース)を所有し、そのアクセス権限を第三者(クライアント)へ付与できるユーザーまたはシステムのことです。

トークンの取得方法についてはリンク先にまとまっている通り、4種類の認証フローがあります。

発行するトークン認証フローリフレッシュトークンの発行有効期限関連リンク
App access token Client credentials grant flow 無し 約2ヶ月
User access token Authorization code grant flow あり 約4時間
Implicit grant flow 無し 約2ヶ月
Device code grant flow あり 約4時間

具体的にどうやってトークンを取得するかは Examples of the four flows に書いていますが、以下にも記載します。
Device code grant flowは私は使ったことがないので他の3つについて説明します。



Client credentials grant flow

Client credentials grant flowは以下の図に示す流れになっています。見てわかる通りかなりシンプルです。
client_credentials_grant_flow

POSTリクエストを発行することで取得できます。curl コマンドなら以下のようになります。

curl -X POST 'https://id.twitch.tv/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=[clientID]&client_secret=[clientSecret]&grant_type=client_credentials'

上記コマンドを実行すると、以下の形式でレスポンスが返ってきます。 access_token に記載されているのが App access token です。

{
  "access_token":"[発行されたトークン]",
  "expires_in":[有効期限],
  "token_type":"bearer"
}

有効期限は約2ヶ月です。
リフレッシュトークンは発行されないため、期限が切れたら再度トークンを取得する必要があります。
POSTリクエストを送信することでトークンを取得できるので、定期的にトークンを再取得する機能を構築して自動化するのが良いと思います。



Authorization code grant flow

Authorization code grant flowは以下の図に示す流れになっています。
oauth
リソースオーナーとは一般的に、『アカウントを持つユーザー本人』を指します。
OAuth 2.0認可フレームワークにおいて、保護されたデータやサービス(リソース)を所有し、そのアクセス権限を第三者(クライアント)へ付与できるユーザーまたはシステムのことです。


図の手順について以下に説明します。
リソースオーナー=自分という前提で書いています。

1. 認可リクエスト
以下のような形式の URL をブラウザに入力します。 Implicit grant flowの response_type が token から code に変わる以外は同じです。

https://id.twitch.tv/oauth2/authorize
?client_id=[clientID]
&force_verify=false
&redirect_uri=[redirectURI]
&response_type=code
&scope=[必要なスコープ]
&state=[state]
  • clientID:アプリケーションの登録で取得したクライアントID
  • force_verify:任意指定項目。ユーザーにアプリのリソースへのアクセスを再承認させる場合はtrueに設定します。デフォルトはfalse
  • redirectURI:アプリケーションの登録で設定したリダイレクトURI
  • response_type:code を指定します。
  • 必要なスコープ:リンク先を参考に必要なスコープを指定
  • state:任意指定項目。CSRF(Cross-Site Request Forgery)対策なので、セキュリティ的には指定した方が安全。任意の文字列を指定。
    リンク先のサンプル では c3ab8aa609ea11e793ae92361f002671 という文字列が設定されている。

必要なスコープは、発行する API ごとに異なります。例えば、投票を開始する API を呼び出す場合、 Polls を見ると「The endpoint requires a user access token with scope channel:manage:polls」とあるので、必要なスコープは「channel:manage:polls」だということがわかります。
この場合、URLに指定するスコープは

channel%3Amanage%3Apolls

となります。ここで「%3A」は「:」のURLエンコードです。
2つ以上のスコープを連結したい場合は「+」で二つのスコープを連結します。

channel%3Amanage%3Apolls+channel%3Aread%3Apolls

これを踏まえ、URL全体としては以下のようになります。

https://id.twitch.tv/oauth2/authorize
?client_id=[clientID]
&redirect_uri=[redirectURI]
&response_type=code
&scope=channel%3Amanage%3Apolls+channel%3Aread%3Apolls
&state=c3ab8aa609ea11e793ae92361f002671

2. ログイン要求
Twitchにログインしていない場合、ログインを要求されます。

3. 認可確認画面
上記をブラウザに入力すると、以下のような認可確認画面が表示されます。
有効期限内のトークンが存在する場合は表示されませんが、force_verify に true を設定することで再承認を強制できます。
authorize_picture

4. アクセス許可
上記画面の「Authorize」ボタンを押下すると、アクセスが許可されます。

5. 認可コード発行
アクセスが許可されると、redirect_uri に指定したURLにリダイレクトされます。
リダイレクト先のURLに、以下のような形式で code が記載されています。これが認可コードです。

[redirectURI]
?code=[発行された認可コード]
&scope=[指定したスコープ]
&state=[指定したstate]

6. トークン発行依頼
発行された認可コードを使用して、以下のような形式のPOSTリクエストを送ると、アクセストークンとリフレッシュトークンが発行されます。

curl -X POST 'https://id.twitch.tv/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=[clientID]&client_secret=[clientSecret]&code=[発行された認可コード]&grant_type=authorization_code&redirect_uri=[redirectURI]'

7. アクセストークン、リフレッシュトークン発行
上記コマンドが成功すると、以下のレスポンスが返ってきます。
リダイレクト先のURLに、以下のようなjsonが返ってきます。
access_token が User access token で、refresh_token が Refresh token です。

{
  "access_token":"[発行されたトークン]",
  "expires_in":15668,
  "refresh_token":"[発行されたリフレッシュトークン]",
  "scope":[指定したスコープ],
  "token_type":"bearer"
}

有効期限は約4時間です。
トークンを再取得する場合は、リフレッシュトークンを使うか、再度Authorization code grant flowを経てトークンを発行する必要があります。



Implicit grant flow

Implicit grant flow は 『認可コードを使用しない Authorization code grant flow』です。
認可コードを使う方式に比べて安全性に問題があるため OAuth としては非推奨の方式であり、OAuth 2.1からは Implicit grant は仕様自体から削除されています。
(2026/4/3現在、TwitchはOAuth 2.0準拠のためImplicit grant flowは使用可能です)
Implicit grant flow は以下の図に示す流れでトークンを取得する方式になっています。
implicit_grant_flow
リソースオーナーとは一般的に、『アカウントを持つユーザー本人』を指します。
OAuth 2.0認可フレームワークにおいて、保護されたデータやサービス(リソース)を所有し、そのアクセス権限を第三者(クライアント)へ付与できるユーザーまたはシステムのことです。


図の手順について以下に説明します。
リソースオーナー=自分という前提で書いています。

1. 認可リクエスト
以下のような形式の URL をブラウザに入力します。 Authorization code grant flowの response_type が code から token に変わる以外は同じです。

https://id.twitch.tv/oauth2/authorize
?client_id=[clientID]
&force_verify=false
&redirect_uri=[redirectURI]
&response_type=token
&scope=[必要なスコープ]
&state=[state]
  • clientID:アプリケーションの登録で取得したクライアントID
  • force_verify:任意指定項目。ユーザーにアプリのリソースへのアクセスを再承認させる場合はtrueに設定します。デフォルトはfalse
  • redirectURI:アプリケーションの登録で設定したリダイレクトURI
  • response_type:token を指定します。
  • 必要なスコープ:リンク先を参考に必要なスコープを指定
  • state:任意指定項目。CSRF(Cross-Site Request Forgery)対策なので、セキュリティ的には指定した方が安全。任意の文字列を指定。
    リンク先のサンプル では c3ab8aa609ea11e793ae92361f002671 という文字列が設定されている。

必要なスコープは、発行する API ごとに異なります。例えば、投票を開始する API を呼び出す場合、 Polls を見ると「The endpoint requires a user access token with scope channel:manage:polls」とあるので、必要なスコープは「channel:manage:polls」だということがわかります。
この場合、URLに指定するスコープは

channel%3Amanage%3Apolls

となります。ここで「%3A」は「:」のURLエンコードです。
2つ以上のスコープを連結したい場合は「+」で二つのスコープを連結します。

channel%3Amanage%3Apolls+channel%3Aread%3Apolls

これを踏まえ、URL全体としては以下のようになります。

https://id.twitch.tv/oauth2/authorize
?client_id=[clientID]
&redirect_uri=[redirectURI]
&response_type=token
&scope=channel%3Amanage%3Apolls+channel%3Aread%3Apolls
&state=c3ab8aa609ea11e793ae92361f002671

2. ログイン要求
Twitchにログインしていない場合、ログインを要求されます。

3. 認可確認画面
上記をブラウザに入力すると、以下のような認可確認画面が表示されます。
有効期限内のトークンが存在する場合は表示されませんが、force_verify に true を設定することで再承認を強制できます。
authorize_picture

4. アクセス許可
上記画面の「Authorize」ボタンを押下すると、アクセスが許可されます。

5. アクセストークン発行
アクセスが許可されると、redirect_uri に指定したURLにリダイレクトされます。
リダイレクト先のURLに、以下のような形式で access_token が記載されています。これが User access token です。

[指定したリダイレクトURL]/
#access_token=[発行されたトークン]
&scope=[指定したスコープ]
&state=[指定したstate]
&token_type=bearer

有効期限は約2か月です。
リフレッシュトークンは発行されないため、期限が切れたら再度トークンを取得する必要があります。
このプロセスを自動化するのはなかなか難しいので、自動化したい場合はAuthorization code grant flowを使用するのが良いでしょう。
セキュリティ上の理由でもそちらが推奨されます。



リフレッシュトークン

リフレッシュトークンは、User access token を再取得するためのトークンです。
Authorization code grant flowでUser access tokenを発行するとリフレッシュトークンも同時に発行されるため、これを使えば期限切れの前にトークンを再取得することができます。
POSTリクエストを発行することで再取得できます。curl コマンドなら以下のようになります。

curl -X POST 'https://id.twitch.tv/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'client_id=[clientID]&client_secret=[clientSecret]&refresh_token=[refreshToken]&grant_type=refresh_token'

上記コマンドを実行すると、以下の形式でレスポンスが返ってきます。 access_token に記載されているのが User access token です。
リフレッシュトークンも再発行されます。

{
  "access_token":"[発行されたトークン]",
  "expires_in":[有効期限],
  "refresh_token":"[発行されたリフレッシュトークン]",
  "scope":[指定したスコープ],
  "token_type":"bearer"
}

POSTリクエストを送信することでトークンを取得できるので、定期的にトークンを再取得する機能を構築して自動化するのが良いと思います。




参考サイト