OAuth 2.0 全フローの図解と動画

  • 1085
    いいね
  • 0
    コメント

RFC 6749 (The OAuth 2.0 Authorization Framework) で定義されている 4 つの認可フロー、および、リフレッシュトークンを用いてアクセストークンの再発行を受けるフローの図解及び動画です。動画は YouTube へのリンクとなっています。

English version: Diagrams And Movies Of All The OAuth 2.0 Flows

1. 認可コードフロー

RFC 6749, 4.1. Authorization Code Grant で定義されているフローです。認可エンドポイントに認可リクエストを投げ、応答として短命の認可コードを受けとり、その認可コードをトークンエンドポイントでアクセストークンと交換するフローです。

動画: OAuth 2.0, Authorization Code Flow (in Japanese)
RFC6749-4_1-authorization_code_flow-Japanese.png

1.1. 認可エンドポイントへのリクエスト

GET {認可エンドポイント}
  ?response_type=code            // 必須
  &client_id={クライアントID}      // 必須
  &redirect_uri={リダイレクトURI}  // 条件により必須
  &scope={スコープ群}              // 任意
  &state={任意文字列}              // 推奨
  HTTP/1.1
HOST: {認可サーバー}

1.2. 認可エンドポイントからのレスポンス

HTTP/1.1 302 Found
Location: {リダイレクトURI}
  ?code={認可コード}        // 必須
  &state={任意文字列}       // 認可リクエストに state が含まれていれば必須

1.3. トークンエンドポイントへのリクエスト

POST {トークンエンドポイント} HTTP/1.1
Host: {認可サーバー}
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code   // 必須
&code={認可コード}                // 必須 認可エンドポイントのレスポンスに含まれる値を指定
&redirect_uri={リダイレクトURI}   // 認可リクエストに redirect_uri が含まれていれば必須

条件によってはクライアント認証を求められることがあり、その場合は Basic 認証(Authorization ヘッダー)もしくは client_id & client_secret パラメーターを追加します。

1.4. トークンエンドポイントからのレスポンス

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"{アクセストークン}",     // 必須
  "token_type":"{トークンタイプ}",         // 必須
  "expires_in":{有効秒数},                // 任意
  "refresh_token":"{リフレッシュトークン}", // 任意
  "scope":"{スコープ群}"                  // 要求したスコープ群と差異があれば必須
}

2. インプリシットフロー

RFC 6749, 4.2. Implicit Grant で定義されているフローです。認可エンドポイントに認可リクエストを投げ、応答として直接アクセストークンを受け取るフローです。

動画: OAuth 2.0, Implicit Flow (in Japanese)
RFC6749-4_2-implicit_flow-Japanese.png

2.1. 認可エンドポイントへのリクエスト

GET {認可エンドポイント}
  ?response_type=token           // 必須
  &client_id={クライアントID}      // 必須
  &redirect_uri={リダイレクトURI}  // 条件により必須
  &scope={スコープ群}              // 任意
  &state={任意文字列}              // 推奨
  HTTP/1.1
HOST: {認可サーバー}

2.2. 認可エンドポイントからのレスポンス

HTTP/1.1 302 Found
Location: {リダイレクトURI}
  #access_token={アクセストークン} // 必須
  &token_type={トークンタイプ}     // 必須
  &expires_in={有効秒数}          // 任意
  &state={任意文字列}             // 認可リクエストに state が含まれていれば必須
  &scope={スコープ群}             // 要求したスコープ群と差異があれば必須

インプリシットフローではリフレッシュトークンは発行されません。

3. リソースオーナー・パスワード・クレデンシャルズフロー

RFC 6749, 4.3. Resource Owner Password Credentials Grant で定義されているフローです。トークンエンドポイントに認可リクエストを投げ、応答としてアクセストークンを受け取るフローです。OAuth のフローですが、クライアントアプリケーションがユーザーの ID とパスワードを受けとります。このフローについては、「OAuth 2.0 + OpenID Connect のフルスクラッチ実装者が知見を語る」の「Resource Owner Password Credentials Grant について」もご参照ください。

動画: OAuth 2.0, Resource Owner Password Credentials Flow (in Japanese)
RFC6749-4_3-resource_owner_password_credentials_flow-Japanese.png

3.1. トークンエンドポイントへのリクエスト

POST {トークンエンドポイント} HTTP/1.1
Host: {認可サーバー}
Content-Type: application/x-www-form-urlencoded

grant_type=password     // 必須
&username={ユーザーID}    // 必須
&password={パスワード}    // 必須
&scope={スコープ群}       // 任意

条件によってはクライアント認証を求められることがあり、その場合は Basic 認証(Authorization ヘッダー)もしくは client_id & client_secret パラメーターを追加します。

3.2. トークンエンドポイントからのレスポンス

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"{アクセストークン}",     // 必須
  "token_type":"{トークンタイプ}",         // 必須
  "expires_in":{有効秒数},                // 任意
  "refresh_token":"{リフレッシュトークン}", // 任意
  "scope":"{スコープ群}"                  // 要求したスコープ群と差異があれば必須
}

4. クライアント・クレデンシャルズフロー

RFC 6749, 4.4. Client Credentials Grant で定義されているフローです。トークンエンドポイントに認可リクエストを投げ、応答としてアクセストークンを受け取るフローです。このフローでは、ユーザーの認証はおこなわれず、クライアントアプリケーションの認証のみがおこなわれます。

動画: OAuth 2.0, Client Credentials Flow (in Japanese)
RFC6749-4_4-client_credentials_flow-Japanese.png

4.1. トークンエンドポイントへのリクエスト

POST {トークンエンドポイント} HTTP/1.1
Host: {認可サーバー}
Authorization: Basic {クライアントクレデンシャルズ}
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials     // 必須
&scope={スコープ群}                 // 任意

クライアント・クレデンシャルズフローは、confidential クライアント (RFC 6749, 2.1. Client Types 参照) のみに許されており、結果、必ずクライアント認証が求められます。Basic 認証(Authorization ヘッダー)もしくは client_id & client_secret パラメーターが必要になります。

4.2. トークンエンドポイントからのレスポンス

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"{アクセストークン}",   // 必須
  "token_type":"{トークンタイプ}",       // 必須
  "expires_in":{有効秒数},              // 任意
  "scope":"{スコープ群}"                // 要求したスコープ群と差異があれば必須
}

クライアント・クレデンシャルズフローでは、リフレッシュトークンを発行すべきではないとされています。

5. リフレッシュトークンフロー

RFC 6749, 6. Refreshing an Access Token で定義されているフローです。事前に発行を受けていたリフレッシュトークンをトークンエンドポイントに提示することにより、アクセストークンの再発行を受けます。

動画: OAuth 2.0, Refresh Token Flow (in Japanese)
RFC6749-6-refresh_token_flow-Japanese.png

5.1. トークンエンドポイントへのリクエスト

POST {トークンエンドポイント} HTTP/1.1
Host: {認可サーバー}
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token             // 必須
&refresh_token={リフレッシュトークン}    // 必須
&scope={スコープ群}                    // 任意

条件によってはクライアント認証を求められることがあり、その場合は Basic 認証(Authorization ヘッダー)もしくは client_id & client_secret パラメーターを追加します。

5.2. トークンエンドポイントからのレスポンス

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"{アクセストークン}",     // 必須
  "token_type":"{トークンタイプ}",         // 必須
  "expires_in":{有効秒数},                // 任意
  "refresh_token":"{リフレッシュトークン}", // 任意
  "scope":"{スコープ群}"                  // 元のスコープ群と差異があれば必須
}

まとめ

フロー 認可エンドポイント トークンエンドポイント 特徴
認可コード 使う 使う 短命の認可コードの発行を受け、トークンエンドポイントでアクセストークンと交換する。
インプリシット 使う 使わない 認可エンドポイントから直接アクセストークンの発行を受ける。
リソースオーナー・パスワード・クレデンシャルズ 使わない 使う ユーザーの ID とパスワードをクライアントに渡す。
クライアント・クレデンシャルズ 使わない 使う クライアントアプリの認証のみでアクセストークンの発行を受ける。
リフレッシュトークン 使わない 使う リフレッシュトークンを提示してアクセストークンの再発行を受ける。