OAuth Grant Types 概要

* OAuthの以下の認可方式についてメモする。
  * Authorization Code
  * Client Credentials
  * Device Code
  * Refresh Token



## Authorization Code

### **概要**

* 認可エンドポイントに認可リクエストを行い、レスポンスとして認可コードを受け取り、トークンエンドポイントでその認可コードとアクセストークンを交換する認可方式。

### **シーケンス**
![ACG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/cae9669f-d549-e47a-6294-642afaa06061.png)


### 認可エンドポイント

* リクエスト

  ```http
  GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
     &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
  Host: server.example.com
  ```


| パラメータ    | 説明                   |
| ------------- | ---------------------- |
| response_type | `code`を指定           |
| client_id     | クライアントID         |
| state         | 任意のCSRF対策用文字列 |
| redirect_uri  | リダイレクトURI        |


* レスポンス

  ```http
  HTTP/1.1 302 Found
  Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
  &state=xyz
  ```

| パラメータ | 説明                                       |
| ---------- | ------------------------------------------ |
| code       | 認可サーバーが発行した認可コード           |
| state      | 認可リクエストで受け取ったCSRF対策用文字列 |

### トークンエンドポイント

* リクエスト

```http
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
```

| パラメータ   | 説明                                 |
| ------------ | ------------------------------------ |
| grant_type   | `authorization_code`を指定           |
| code         | 認可レスポンスで受け取った認可コード |
| redirect_uri | 認可コードの受取先                   |

* レスポンス

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

{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "token_type":"example",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "example_parameter":"example_value"
}
```

| パラメータ    | 説明                                      |
| ------------- | ----------------------------------------- |
| access_token  | アクセストークン                          |
| token_type    | トークン種別                              |
| expires_in    | アクセストークン有効秒数                  |
| scope         | スコープ※オプション                       |
| refresh_token | アクセストークン再発行用識別子※オプション |



## Client Credentials

### 概要

* トークンエンドポイントにトークンリクエストを行い、レスポンスとしてアクセストークンを受け取る認可方式。
* ユーザー認証は実施せず、クライアントアプリの認証のみ行う。

### シーケンス
![ClientCredentialsGrant.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/f78a91c0-962b-2f03-3fd0-63ec076e1180.png)

### トークンエンドポイント

* リクエスト

  ```http
  POST /token HTTP/1.1
  Host: server.example.com
  Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
  Content-Type: application/x-www-form-urlencoded
  
  grant_type=client_credentials
  ```

| パラメータ | 説明                       |
| ---------- | -------------------------- |
| grant_type | `client_credentials`を指定 |
| scope      | スコープ※オプション        |

* レスポンス

| パラメータ    | 説明                                      |
| ------------- | ----------------------------------------- |
| access_token  | アクセストークン                          |
| token_type    | トークン種別                              |
| expires_in    | アクセストークン有効秒数                  |
| scope         | スコープ※オプション                       |
| refresh_token | アクセストークン再発行用識別子※オプション |

## Device Code

### 概要

* 過去に取得したデバイスコードをアクセストークンと交換する認可方式。
* Web ブラウザを搭載していないデバイスや文字入力方法などに著しい制限のあるデバイス上で動くクライアントアプリ向け。

### シーケンス
![Device.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/068b7303-e780-0906-b0d1-3f0baada8488.png)


### デバイス認可エンドポイント

* リクエスト

```http
POST /device_authorization HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
client_id=1406020730&scope=example_scope
```

| パラメータ | 説明                    |
| ---------- | ----------------------- |
| client_id  | クライアント識別子※必須 |
| scope      | スコープ※オプション     |

* レスポンス

  ```http
  HTTP/1.1 200 OK
  Content-Type: application/json
  Cache-Control: no-store
  {
     "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
     "user_code": "WDJB-MJHT",
     "verification_uri": "https://example.com/device",
     "verification_uri_complete":
    "https://example.com/device?user_code=WDJB-MJHT",
     "expires_in": 1800,
     "interval": 5
  }
  ```

| パラメーター              | 説明                                                  |
| :------------------------ | :---------------------------------------------------- |
| device_code               | デバイス確認コード※必須                               |
| user_code                 | エンドユーザー確認コード※必須                         |
| verification_uri          | (認可サーバーの)エンドユーザー検証 URI※必須           |
| verification_uri_complete | user_code を含むエンドユーザー検証 URI※オプション     |
| expires_in                | device_codeとuser_code の有効期間(秒)※必須            |
| interval                  | トークンリクエストの最小ポーリング間隔(秒)※オプション |

### デバイストークンエンドポイント

※デバイス認可エンドポイントからレスポンスを受け取ったあと、最終結果が得られるまでリクエストを行う。

* リクエスト

  ```http
  POST /token HTTP/1.1
  Host: server.example.com
  Content-Type: application/x-www-form-urlencoded
  
  grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code
  &device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS
  &client_id=1406020730
  ```

| パラメーター | 説明                                                |
| :----------- | :-------------------------------------------------- |
| device_code  | デバイス確認コード※必須                             |
| grant_type   | `urn:ietf:params:oauth:grant-type:device_code`※必須 |
| client_id    | クライアントID※必須                                 |

* レスポンス

  * 正常系レスポンスは他の認可方式と同じ。
  * エラーコード `authorization_pending` もしくは `slow_down` を受け取る間、クライアントアプリはトークンリクエストを繰り返す。



## Refresh Token

### 概要

* 事前に発行をされたリフレッシュトークンをトークンエンドポイントに提示し、アクセストークンの再発行を行う認可方式。

### シーケンス

![RT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/7e92e350-2a96-2512-c801-46d051a54114.png)


### トークンエンドポイント

* リクエスト

```http
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
```

| パラメーター  | 説明                                                        |
| :------------ | :---------------------------------------------------------- |
| refresh_token | アクセストークン発行時に受け取ったリフレッシュトークン※必須 |
| grant_type    | `refresh_token`※必須                                        |

* レスポンス

  * 他の認可方式と同じ内容。

  

## 参考情報

* [OAuth Grant Types](https://oauth.net/2/grant-types/)
* [OAuth 2.0 Device Authorization Grant](https://tools.ietf.org/html/rfc8628)
* [The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749#section-6)