Help us understand the problem. What is going on with this article?

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

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

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

追記 (2019-07-02)
認可決定エンドポイントからクライアントに認可コードやアクセストークンを渡す方法については、別記事『OAuth 2.0 の認可レスポンスとリダイレクトに関する説明』で解説していますので、ご参照ください。

追記(2020-03-20)
この記事の内容を含む、筆者本人による『OAuth & OIDC 入門編』解説動画を公開しました!

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={任意文字列}              // 推奨
  &code_challenge={チャレンジ}     // 任意
  &code_challege_method={メソッド} // 任意
  HTTP/1.1
HOST: {認可サーバー}

※:上記は、RFC 6749 に加え RFC 7636 で定義されたリクエストパラメーターも含んでいます。詳細はこちら

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 が含まれていれば必須
&code_verifier={ベリファイア}     // 認可リクエストに code_challenge が含まれていれば必須

※:上記は、RFC 6749 に加え RFC 7636 で定義されたリクエストパラメーターも含んでいます。詳細はこちら

クライアントのクライアントタイプが public の場合は client_id リクエストパラメーターが追加で必要です。一方、confidential の場合は、クライアント認証の方法により、Authorization ヘッダーや client_id & client_secret パラメーターなどが追加で必要になります。詳細は『OAuth 2.0 クライアント認証』を参照してください。

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)
Resource-Owner-Password-Credentials-Flow-in-Japanese.png

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

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

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

クライアントのクライアントタイプが public の場合は client_id リクエストパラメーターが追加で必要です。一方、confidential の場合は、クライアント認証の方法により、Authorization ヘッダーや client_id & client_secret パラメーターなどが追加で必要になります。詳細は『OAuth 2.0 クライアント認証』を参照してください。

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)
Client-Credentials-Flow-in-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 参照) のみに許されており、結果、必ずクライアント認証が求められます。

クライアント認証の方法により、Authorization ヘッダーや client_id & client_secret パラメーターなどが追加で必要になります。詳細は『OAuth 2.0 クライアント認証』を参照してください。

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)
Refresh-Token-Flow-in-Japanese.png

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

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

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

クライアントのクライアントタイプが public の場合は client_id リクエストパラメーターが追加で必要です。一方、confidential の場合は、クライアント認証の方法により、Authorization ヘッダーや client_id & client_secret パラメーターなどが追加で必要になります。詳細は『OAuth 2.0 クライアント認証』を参照してください。

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 とパスワードをクライアントに渡す。
クライアント・クレデンシャルズ 使わない 使う クライアントアプリの認証のみでアクセストークンの発行を受ける。
リフレッシュトークン 使わない 使う リフレッシュトークンを提示してアクセストークンの再発行を受ける。

おまけ

OAuth 2.0 や OpenID Connect、UMA など、数多くの標準仕様の策定に携わり、『OAuth 2 in Action』の著者としても知られる Justin Richer 氏が、2017 年 7 月 27 日に『Deployment and Hosting Patterns in OAuth』という記事を公開しました。 その記事の中で彼は、認可サーバーの実装方法を 4 つに分類し、『Semi-Hosted Service パターン』の例として Authlete(オースリート)に言及しました。 詳細は『OAuth 2.0 / OIDC 実装の新アーキテクチャー』をご参照ください。

Semi-Hosted Service パターンでは、認可機能を提供するバックエンドサービスを利用して、フロントの認可サーバーを実装します。 この実装方法のアーキテクチャーは通常の認可サーバーのそれより当然複雑になりますが、その利点は何かというと、バックエンドサービスが OAuth 2.0 と OpenID Connect の実装に専門特化できることです。 アイデンティティー管理やユーザー認証、セッション管理、API 管理、不正検出など、API まわりの他の技術要素から独立し、OAuth 2.0 と OpenID Connect の実装に集中することができます。 このアーキテクチャーから必然的に導かれるもう一つの利点は、バックエンドサービス(OAuth 2.0 と OpenID Connect の実装)を、他の技術要素のどのようなソリューションとも組み合わせることができることです。 例えば、ユーザー認証にどのような方法を用いてもよく、FIDO のような新しい認証ソリューションが登場しても、問題無く対応できます。

ここでは、おまけとして、Authlete をバックエンドサービスとして用いたときに OAuth 2.0 の各フローがどのように実装されることになるかを、図でご紹介します。 丁寧に図を見ていただくと、Authlete がどうして「どんなユーザー認証方法とも組み合わせることができる」のかが分かると思います。

認可コードフロー + Authlete

OAuth-Flows+Authlete-in-Japanese_2_Authorization-Code-Flow.png

インプリシットフロー + Authlete

OAuth-Flows+Authlete-in-Japanese_3_Implicit-Flow.png

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

OAuth-Flows+Authlete-in-Japanese_4_Resource-Owner-Password-Credentials-Flow.png

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

OAuth-Flows+Authlete-in-Japanese_5_Client-Credentials-Flow.png

リフレッシュトークンフロー + Authlete

OAuth-Flows+Authlete-in-Japanese_6_Refresh-Token-Flow.png

TakahikoKawasaki
株式会社 Authlete の共同創業者。プログラマー兼代表取締役社長。
https://www.authlete.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした