OAuth 2.0 認可コードグラント概要

OAuth2.0の概要と、そのグラントタイプの一つである認可コードグラントについて説明する。


## OAuth2.0 とは？

サードパーティアプリによる、ユーザーのリソースを保持するHTTPサービスへの限定的なアクセス(一部の操作)を可能にする認可フレームワーク(アクセストークンの発行方法に関するルール)のこと。
![OAuth2_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/1f42f925-f9f9-7f37-8ef7-a6505dc96be2.png)

## OAuth2.0 が、なぜ必要か？

* ユーザーのリソースを利用したい3rdパーティアプリから、ユーザーのリソースに安全に(リソースを保持するサービスのユーザーID、パスワードを保持せず、)アクセスするため。
    * 3rdパーティアプリが、ユーザーID、パスワードを保持している場合...
        * 3rdパーティアプリが、悪意ある開発者によって作られたアプリである場合、ユーザーのデータに対してあらゆる操作を行うことができてしまう。
        * 3rdパーティアプリが、悪意ある人物から攻撃を受けた場合、ユーザー名、パスワードが漏洩してしまう可能性がある。

## OAuth2.0ロールと関係性
![OAuth2_関係.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/d73bb52b-99a6-50d3-d392-2811c610bcd0.png)

|ロール  |説明  |
|---|---|
|リソースオーナー  |サービスで管理しているリソースの所有者。3rdパーティアプリにアクセス権を委譲して、リソースにアクセスする。  |
|クライアント  |リソースサーバーを利用するアプリケーション。ユーザーによって委譲されたアクセス権の範囲で、リソースにアクセスする。  |
|リソースサーバー |データや機能を提供するサービス。リソースオーナーのリソースを管理し、リソースオーナーが許可したアクセスのみを受け入れる。アクセス権の確認には、アクセストークンを利用する。|
|認可サーバー  |以下の機能を持つサーバー。<br>・リソースオーナーを認証(リソースオーナーであることを確認)する。<br/>・クライアントのリソースへのアクセスについて、リソースオーナーの同意を得る。<br>・アクセストークンを発行する。|
    	
1. クライアントは、リソースへのアクセス権を、認可サーバーに要求する。
2. 認可サーバーは、クライアントへのアクセス権の委譲を、リソースオーナーに確認する。
3. リソースオーナーは、クライアントへのアクセス権の委譲に同意する。
4. 認可サーバーは、クライアントに対してアクセストークン(アクセス権がクライアントへ委譲された証)を発行する。
5. クライアントは、アクセストークンを使用してリソースにアクセスする。

## 認可コードグラント

OAuth2.0には、アクセス権の付与の方法(グラントタイプ)が複数定義されている。その中の一つ、認可コードグラント(Authorization Code Grant)について説明する。パブリッククライアント用のグラントタイプとして「PKCEを用いた認可コードグラント」も存在するが、ここでは記載しない。

### 特徴:セキュア
- アクセストークンを、クライアントと認可サーバー間で直接受け渡すため、流出のリスクが低い。
- 相手が正しいことを確認しながら、やりとりを行う。
  - 認可サーバーは、認証情報(ユーザーID/パスワード) の入力により、リソースオーナーの認証を行う。
  - 認可サーバーは、HTTP Basic認証によってアクセス元クライアントのクライアントID/シークレットを確認する。
  - クライアントは、URIとSSL証明書によって、アクセス先認可サーバーのアイデンティティを確認する。

### シーケンス
![OAuth2_ACG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/70dd8be9-5d31-d20c-8542-c9ad0c4a944d.png)

処理としては、大きく３つに分かれる。

#### ①認可コードの取得

1. クライアントのリソースサーバーへのアクセスを要求するボタンを押す。
2. クライアントは、HTTPステータスコード302を返却し、リダイレクトすることで、リソースオーナーを認可エンドポイントに導く(=認可リクエストと呼ぶ)。
   - 認可エンドポイントにはリクエストに必要な情報がクエリパラメーターとして付与される。 
3. 認可サーバーは、リソースオーナーにログイン画面を表示し、認証情報(ユーザーID/パスワード)入力を求める。入力値が正しい場合、認証が完了する。
   - この認証処理に、クライアントが介在しないため、クライアントがユーザーの認証情報を知ることはない。
4. 認可サーバーは、クライアントが要求する権限の一覧をリソースオーナーに対して表示する。
   - 認可サーバーは、認可リクエストでクライアントが指定したスコープにそって、権限の一覧を表示する。
5. リソースオーナーは、権限をクライアントに委譲することについて同意または拒否を選択する。
6. (リソースオーナーが、クライアントへの権限移譲に同意した場合、)認可サーバーがステータスコード302のレスポンスを返す(=認可レスポンスと呼ぶ)。
   - `Location`ヘッダーには、2で指定したリダイレクトURIが設定される。

#### ②アクセストークンの取得

1. 取得した認可コードを付与して、クライアントからトークエンドポイントにリクエストを投げる(＝トークンリクエストと呼ぶ)。
   - Basic認証の仕組みを使って、クライアントID/シークレットの値を送付。

#### ③リソースへのアクセス

1. クライアントは、アクセストークンを利用して、リソースサーバーのリソースにアクセスする。
  - `Authorization`ヘッダーに`Bearer`という文字列とともにアクセストークンの値を設定する。
2. リソースサーバーは、アクセストークンが適切な権限を持っているかをチェックし、(適切であれば、)要求されたリソースを提供する。


## 参考書籍
* [雰囲気で使わずきちんと理解する！整理してOAuth2.0を使うためのチュートリアルガイド](https://www.amazon.co.jp/%E9%9B%B0%E5%9B%B2%E6%B0%97%E3%81%A7%E4%BD%BF%E3%82%8F%E3%81%9A%E3%81%8D%E3%81%A1%E3%82%93%E3%81%A8%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B%EF%BC%81%E6%95%B4%E7%90%86%E3%81%97%E3%81%A6OAuth2-0%E3%82%92%E4%BD%BF%E3%81%86%E3%81%9F%E3%82%81%E3%81%AE%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%AC%E3%82%A4%E3%83%89-%E6%8A%80%E8%A1%93%E3%81%AE%E6%B3%89%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA%EF%BC%88NextPublishing%EF%BC%89-Auth%E5%B1%8B-ebook/dp/B07XT8H2YG)
    * 非常に参考にさせていただきました。