4. Protocol (プロトコル)
4.1 Client Creates a Code Verifier (クライアントによるコード検証子の作成)
クライアントは、まず、各OAuth 2.0 [RFC6749]認可リクエストに対して、以下の方法でコード検証子「code_verifier」を作成します:
code_verifier = [RFC3986]のセクション2.3の未予約文字
[A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"
を使用した高エントロピーの暗号的にランダムなSTRING、
最小長43文字、最大長128文字。
「code_verifier」のABNFは以下のとおりです。
code-verifier = 43*128unreserved
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
ALPHA = %x41-5A / %x61-7A
DIGIT = %x30-39
注意: コード検証子は、その値を推測することが実用的でないように、十分なエントロピーを持つべきです (すべきである)。32オクテットのシーケンスを作成するために、適切な乱数ジェネレータの出力を使用することが推奨されます (推奨される)。次に、このオクテットシーケンスをbase64urlエンコードして、コード検証子として使用する43オクテットのURLセーフ文字列を生成します。
4.2 Client Creates the Code Challenge (クライアントによるコードチャレンジの作成)
次に、クライアントは、コード検証子に対して以下のいずれかの変換を使用して、コード検証子から導出されたコードチャレンジを作成します:
plain
code_challenge = code_verifier
S256
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
クライアントが「S256」を使用できる場合は、「S256」を使用しなければなりません (必須である)。「S256」はサーバー上で実装必須 (Mandatory To Implement, MTI) であるためです。クライアントが「plain」を使用することが許可されるのは、何らかの技術的な理由で「S256」をサポートできず、アウトオブバンド構成を通じてサーバーが「plain」をサポートしていることを知っている場合のみです。
plain変換は、既存のデプロイメントとの互換性、およびS256変換を使用できない制約のある環境のためのものです。
「code_challenge」のABNFは以下のとおりです。
code-challenge = 43*128unreserved
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
ALPHA = %x41-5A / %x61-7A
DIGIT = %x30-39
4.3 Client Sends the Code Challenge with the Authorization Request (認可リクエストとともにコードチャレンジを送信)
クライアントは、以下の追加パラメータを使用して、OAuth 2.0認可リクエスト ([RFC6749]のセクション4.1.1)の一部としてコードチャレンジを送信します:
code_challenge : 必須 (REQUIRED)。コードチャレンジ。
code_challenge_method : オプション (OPTIONAL)。リクエストに存在しない場合、デフォルトは「plain」です。コード検証子変換方法は「S256」または「plain」です。
4.4 Server Returns the Code (サーバーによるコードの返却)
サーバーが認可レスポンスで認可コードを発行する際、後で検証できるように、「code_challenge」と「code_challenge_method」の値を認可コードに関連付けなければなりません (しなければならない)。
通常、「code_challenge」と「code_challenge_method」の値は、「code」自体に暗号化された形式で保存されますが、サーバー上でコードに関連付けて保存することもできます。サーバーは、他のエンティティが抽出できる形式で、クライアントリクエストに「code_challenge」値を含めてはなりません (禁止される)。
サーバーが「code_challenge」を発行された「code」に関連付けるために使用する正確な方法は、本仕様書の範囲外です。
4.4.1 Error Response (エラーレスポンス)
サーバーがOAuthパブリッククライアントにProof Key for Code Exchange (PKCE) を要求し、クライアントがリクエストで「code_challenge」を送信しない場合、認可エンドポイントは、「error」値を「invalid_request」に設定した認可エラーレスポンスを返さなければなりません (しなければならない)。「error_description」または「error_uri」のレスポンスは、エラーの性質(例えば、コードチャレンジが必要)を説明すべきです (すべきである)。
PKCEをサポートするサーバーが要求された変換をサポートしていない場合、認可エンドポイントは、「error」値を「invalid_request」に設定した認可エラーレスポンスを返さなければなりません (しなければならない)。「error_description」または「error_uri」のレスポンスは、エラーの性質(例えば、変換アルゴリズムがサポートされていない)を説明すべきです (すべきである)。
4.5 Client Sends the Authorization Code and the Code Verifier to the Token Endpoint (トークンエンドポイントへの認可コードとコード検証子の送信)
認可コードを受信すると、クライアントはアクセストークンリクエストをトークンエンドポイントに送信します。OAuth 2.0アクセストークンリクエスト ([RFC6749]のセクション4.1.3) で定義されたパラメータに加えて、以下のパラメータを送信します:
code_verifier : 必須 (REQUIRED)。コード検証子。
「code_challenge_method」は、認可コードが発行されるときに認可コードにバインドされます。これは、トークンエンドポイントが「code_verifier」を検証するために使用しなければならない (必須である) 方法です。
4.6 Server Verifies code_verifier before Returning the Tokens (トークン返却前のcode_verifierの検証)
トークンエンドポイントでリクエストを受信すると、サーバーは、受信した「code_verifier」からコードチャレンジを計算し、それを以前に関連付けられた「code_challenge」と比較して、最初にクライアントが指定した「code_challenge_method」方法に従って変換してから検証します。
セクション4.3の「code_challenge_method」が「S256」の場合、受信した「code_verifier」はSHA-256でハッシュ化され、base64urlエンコードされ、次に「code_challenge」と比較されます。つまり:
BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) == code_challenge
セクション4.3の「code_challenge_method」が「plain」の場合、それらは直接比較されます。つまり:
code_verifier == code_challenge
値が等しい場合、トークンエンドポイントは、(OAuth 2.0 [RFC6749]で定義されているように)通常の処理を続けなければなりません (しなければならない)。値が等しくない場合は、「invalid_grant」を示すエラーレスポンスを返さなければなりません (しなければならない)([RFC6749]のセクション5.2に記載されているとおり)。