> ## Documentation Index
> Fetch the complete documentation index at: https://developers.authlete.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Proof Key for Code Exchange (RFC 7636)

> RFC 7636 にて定義されている PKCE に関する技術情報です。

<Note>
  このページは Authlete 3.0 用です。2.x については[こちらのページ](/ja/v2/protocols-and-flows/protocol-extensions/pkce)をご覧ください。
</Note>

# 1. イントロダクション

[RFC 7636](http://tools.ietf.org/html/rfc7636)： **Proof Key for Code Exchange** (PKCE, 「ピクシー」と発音します) は、 **認可コード横取り攻撃（authorization code interception attack）** への対策に関する仕様です。

<img alt="authorization code interception attack" class="mx-auto d-block" src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/authorization_code_interception_attack.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=7d65ff051ff2e6a0b8a32681a778dd93" width="691" height="435" data-path="configuration-reference/endpoints/authorization_code_interception_attack.png" />

2015 年 9 月に出版された同仕様は、**認可コードフローの各種リクエストに関し、いくつかの追加パラメーターを定義しています**。

1. 認可リクエスト： `code_challenge` パラメーターと `code_challenge_method` パラメーターを追加
2. トークンリクエスト： `code_verifier` パラメーターを追加

この仕様により認可サーバーは、悪意のある（正当なコードベリファイアを持たない）クライアントアプリからのトークンリクエストを拒否できるようになります。

# 2. PKCE 認可リクエスト

## 2.1 リクエストパラメーター

PKCE に対応したクライアントアプリは、認可リクエストに `code_challenge` パラメーターを追加し、その値としてコードチャレンジを含めます。

`code_challenge_method` パラメーターはオプションです。ただし特別な理由がない限りは、コードチャレンジメソッドとして後述する `S256` の利用が推奨されています。そのため結果的には、`S256` を値として指定するために、`code_challenge_method` パラメーターも追加することになります。

## 2.2 コードチャレンジ

クライアントアプリは、コードベリファイアの値にコードチャレンジメソッドの計算ロジックを適用して、コードチャレンジの値を導出します。

## 2.3 コードベリファイア

クライアントアプリが生成しなくてはならないコードベリファイアの値は、`[A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~"` からなるランダムな文字列であり、最低43文字、最大128文字の長さが必要となります。

<img alt="pkce authorization request" class="mx-auto d-block" src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/pkce_authorization_request.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=36957427425019c9e84d435b0b476f6e" width="477" height="645" data-path="configuration-reference/endpoints/pkce_authorization_request.png" />

## 2.4 コードチャレンジメソッド

コードチャレンジメソッドの値としては `plain` および `S256` が定義されています。それぞれの計算ロジックは下記の通りです。

| Method  | Logic                                                             |
| ------- | ----------------------------------------------------------------- |
| `plain` | code\_challenge = code\_verifier                                  |
| `S256`  | code\_challenge = BASE64URL-ENCODE(SHA256(ASCII(code\_verifier))) |

`plain` では、インプットは何ら変換されません。コードベリファイアの値が、そのままコードチャレンジの値となります。

`S256` では、SHA-256 のハッシュ値を BASE64-URL エンコードした値を用います。例えば、`code_verifier` の値が `dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk` である場合、`code_challenge` の値は `E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM` となります。

`S256` を用いる場合、クライアントアプリは認可リクエストの中に `code_challenge_method=S256` を含める必要があります。 `code_challenge_method` パラメーターがない場合、認可サーバーは `plain` が使われていると判断し、処理します。

# 3. PKCE 認可レスポンス

認可サーバーは認可コードを生成した後、その値と併せて、認可リクエストに含まれている `code_challenge` の値と `code_challenge_method` の値を、データベース上に保存します。

認可サーバーはこれらの値を、その後クライアントアプリから送られてくるトークンリクエストの検証に用います。

認可エンドポイントから返されるレスポンス自体は、これまでと同様であり、PKCE 特有のパラメーター等はありません。

<img alt="pkce authorization response" class="mx-auto d-block" src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/pkce_authorization_response.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=5602266550adfb6fec44be2a271a153d" width="461" height="621" data-path="configuration-reference/endpoints/pkce_authorization_response.png" />

# 4. PKCE トークンリクエスト

認可サーバーから認可コードを受け取った後、クライアントアプリはトークンリクエストを生成します。トークンリクエストには、認可コードに加え、コードチャレンジの値の元となったコードベリファイアの値を、 `code_verifier` パラメーターの値として含める必要があります。

<img alt="pkce_token_request" class="mx-auto d-block" src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/pkce_token_request.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=fc3fb206ae556b8adf95ce48c3304958" width="430" height="499" data-path="configuration-reference/endpoints/pkce_token_request.png" />

# 5. PKCE トークンレスポンス

## 5.1 コードベリファイアの有無を確認する

PKCE をサポートする認可サーバーは、トークンリクエストに正当なコードベリファイアが含まれているのかを確認します。

この確認は、 grant\_type が authorization\_code であり、トークンリクエスト中の認可コードがコードチャレンジと紐づいている場合に限ります。

これらの条件がそろっていても、トークンリクエスト中にコードベリファイアが含まれていない場合、そのリクエストは悪意のあるクライアントアプリからのリクエストと認識し、認可サーバーはエラーを返します。

## 5.2 コードベリファイアを検証する

認可サーバーは 2 つのコードチャレンジを照合し、トークンリクエストの正当性を検証します。

コードチャレンジの片方は、認可リクエストに含まれていた（認可サーバーがデータベースに保存しておいた）値です。もう片方は、認可リクエストで指定された方法（トークンチャレンジメソッド）を用いて、トークンリクエスト中のコードベリファイアから計算される値です。

もしこれら 2 つのコードチャレンジが同一の場合、そのトークンリクエストを送信してきたクライアントアプリは、先の認可リクエストの送信元だったクライアントアプリと同一であると、認可サーバーは判断します。一致しない場合、認可サーバーは、そのトークンリクエストが悪意のあるクライアントアプリから来たものと判定します。

## 5.3 トークンを発行する

トークンリクエストが正規の場合、認可サーバーは通常通りトークンを発行します。

<img alt="pkce_token_response" class="mx-auto d-block" src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/pkce_token_response.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=cccc8d28ff808b4f33a393dfbdd02665" width="525" height="701" data-path="configuration-reference/endpoints/pkce_token_response.png" />

# 6. PKCE を試す

## 6.1 準備する

### 6.1.1 サインアップする

Authlete のアカウントをお持ちでない場合は、まず初めに[サインアップ](https://so.authlete.com/accounts/signup)してください。

### 6.1.2 サービス API キーとクライアント ID

認可リクエストを実行するためには、サービス API キーと クライアント ID が必要となります。これらはサインアップと同時に発行されています（動作確認用の認可サーバーとクライアントアプリがひとつずつ自動的に生成されています）。

実際の値については、アカウント登録時に送信されるメールの記載や、[管理者コンソール][so_console]および[クライアントコンソール][cd_console]からご確認ください。

### 6.1.3 サービスとクライアントの設定

認可サーバー（[管理者コンソール][so_console]の**サービス**）及びクライアントアプリ ([クライアントコンソール][cd_console]の**アプリ**) の設定は下記を参考にしてください。

Table. Settings of Service in Service Owner Console

| カテゴリ | パラメーター               | 値                                    |
| ---- | -------------------- | ------------------------------------ |
| 認可   | サポートする認可種別           | 少なくとも `AUTHORIZATION_CODE` にチェックを入れる |
| 認可   | サポートする応答種別           | 少なくとも `CODE` にチェック入れる                |
| 認可   | ダイレクト認可エンドポイントの有効化   | `有効`                                 |
| 認可   | ダイレクトトークンエンドポイントの有効化 | `有効`                                 |

Table. Settings of Client in Client Developer Console

| カテゴリ | パラメーター     | 値                                                                                                                              |
| ---- | ---------- | ------------------------------------------------------------------------------------------------------------------------------ |
| 基本情報 | クライアントタイプ  | `PUBLIC` を選択する                                                                                                                 |
| 認可   | 認可種別       | 少なくとも `AUTHORIZATION_CODE` にチェックを入れる                                                                                           |
| 認可   | 応答種別       | 少なくとも `CODE` にチェック入れる                                                                                                          |
| 認可   | リダイレクト URI | [https://api.authlete.com/api/mock/redirection/service-api-key](https://api.authlete.com/api/mock/redirection/service-api-key) |

## 6.2. 認可リクエスト・レスポンス

### 6.2.1. 認可エンドポイントにアクセスする

下記の URL にブラウザからアクセスしてください。その際、*service-api-key* と *client-id* は自身のものに置き換えてください。

```shell theme={null}
https://api.authlete.com/api/auth/authorization/direct/service-api-key
  ?client_id=client-id
  &response_type=code
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256
```

上記にある `code_challenge` と `code_challenge_method` が、これまで説明してきた PKCE 関連のパラメーターです。コードチャレンジメソッドとして `S256` を指定し、コードチャレンジとして、後述するコードベリファイアから計算した値 `E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw` を含めています。

### 6.2.2 認可リクエスト

認可エンドポイントにおいて、認可ページが表示されます。その中にあるログインフォームに、ここでは動作確認として、ログイン ID としてサービスの API キー、パスワードとして同じく API シークレットを入力し、認可ボタンをクリックしてください。なお、API シークレットの値の確認方法については[クイックスタート][gs_2_2]をご参照ください。

<img alt="login form in authorization page" class="mx-auto d-block" src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/login_form_in_authorization_page.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=446eb4a6f066fae59a9144ea3a97f683" width="372" height="233" data-path="configuration-reference/endpoints/login_form_in_authorization_page.png" />

### 6.2.3 認可レスポンス

認可エンドポイントから返されるレスポンスは、ブラウザを介して、クライアントアプリのリダイレクトエンドポイントに送られます。送信先（リダイレクト URI）は、サインアップ時に自動生成された動作確認用のクライアントアプリの情報として、すでに登録されています。実際の送信先は `https://api.authlete.com/api/mock/redirection/service-api-key` になります。

このリダイレクトエンドポイントは、動作確認用に Authlete が用意した実装です。この実装では、認可レスポンスとして受け取った各種パラメーターの値を表示します。たとえば、認可コードを含む認可レスポンスを受け取った場合、リダイレクトエンドポイントはその値を下記のように表示します。

<img alt="authorization_code" class="mx-auto d-block" src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/authorization_code.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=f4599dd96d4418eea682b76a6a49ad12" width="603" height="209" data-path="configuration-reference/endpoints/authorization_code.png" />

加えて、認可エンドポイントから ID トークンが発行されていた（認可レスポンスに ID トークンを含んでいた）場合、ID トークンの内容を表示します。

また、認可コードフローのような、トークンリクエストを行うフローの場合、トークンリクエストを送信するためのフォームが表示されます。

## 6.3 トークンリクエスト

### 6.3.1 トークンリクエストフォーム

直前のセクションでも述べましたが、認可レスポンス中に認可コードが含まれている場合、トークンリクエストを送信するためのフォームが表示されます。

そのフォームには、コードベリファイアを入力する欄があります。ここでは、`dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk` と入力して下さい。

<img alt="token_request_form" class="mx-auto d-block" src="https://mintcdn.com/authlete/EJDZNZMvOu_9CJHJ/configuration-reference/endpoints/token_request_form.png?fit=max&auto=format&n=EJDZNZMvOu_9CJHJ&q=85&s=96f49f1512ff12f94ca39ad1c8fbb8c3" width="570" height="496" data-path="configuration-reference/endpoints/token_request_form.png" />

コードベリファイア付きのトークンリクエストを送信するために、「送信」ボタンをクリックしてください。なお、認可コードは 10 分で失効するように設定されているため、10 分以内にボタンをクリックしてください。

### 6.3.2. トークンレスポンス

認可コードと入力したコードベリファイアが正しい場合、JSON 形式でアクセストークンが返却されます。

```json theme={null}
{
    "access_token": "KPLXrl_wJSHqU708R9kp3bNRGi0LgKUdh0kh-CQhx9g",
    "refresh_token": "YLRJXfratV4yq0_65seCT0bF6YxxgU5jKBUvhOZPrb4",
    "scope": null,
    "token_type": "Bearer",
    "expires_in": 86400
}
```

おめでとうございます！これで、PKCE に対応した認可コードフローでアクセストークンの発行が完了しました。

## 6.4. PKCE Configuration

Authlete では、クライアントに対し、PKCE の利用、およびコードチャレンジメソッド S256 の指定を強制するよう設定可能です。詳細は以下の記事をご参照ください。

* [Knowledge Base / OAuth および OpenID Connect / PKCE (RFC 7636)](https://kb.authlete.com/ja/s/oauth-and-openid-connect/a/pkce-rfc-7636)
  * [認可リクエストにおける PKCE 利用の強制化](https://kb.authlete.com/ja/s/oauth-and-openid-connect/a/requiring-pkce): PKCE を利用するよう、クライアントに強制する設定を説明します。
  * [認可リクエストでの PKCE 利用における S256 指定の強制化](/v2/configuration-reference/authorization-requests/requiring-s256/): コードチャレンジメソッドとして S256 を指定するよう、クライアントに強制する設定を説明します。

[cd_console]: /ja/developers/cd_console

[so_console]: /ja/developers/so_console

[getting_started]: /ja/developers/getting_started

[gs_2_2]: /ja/developers/getting_started/#credentials
