二年目エンジニアが認可コードグラントフローのI/Fについてまとめてみた 

## はじめに

[前回](https://qiita.com/naoya_matsuda/items/a7ff1be7905d45b530c1)は、OAuth2.0 を使用する理由と、認可コードグラントフロー全体像についてまとめました
今回はさらに詳細に、各エンドポイントの単位でまとめます

## アジェンダ

1. 認可コードグラントフロー
1. 認可リクエストの I/F
1. 認可画面の I/F
1. アクセストークンリクエスト
1. まとめ

## 1. 認可コードグラントフロー

[前回](https://qiita.com/naoya_matsuda/items/a7ff1be7905d45b530c1)まとめた図をシーケンス図にすると以下のようになります。
![Authorization_code_ground_flow.png](https://qiita-image-store.s3.amazonaws.com/0/351271/e62f3084-584f-5451-0157-39d7f6ece815.png)
図にするとわかるように、認可サーバに対してのリクエストは三つあります。

### 2. 認可リクエストの I/F
認可画面の URL を取得するためのエンドポイント ①
![Authorization_code_ground_flow_number (1).png](https://qiita-image-store.s3.amazonaws.com/0/351271/6ada75ed-c8d8-224d-fac9-dcdbb59af103.png)


リクエストパラメータ

```
GET

response_type 必須
    値：code
    説明：認可コードグラントフローであることを示す値

client_id 必須
    説明：クライアントを識別するための値

redirect_uri 任意
    説明：➂でリダイレクトする先のURI

scope 任意
    説明：WebAppに認可させる権限の範囲
    例:read+write

state 推奨
    説明：最初に認可を開始したユーザとリダイレクトを行ったユーザが一意であることを確認するための値(CSRF対策の値)。セッション

例)
    GET /api/v1/oauth/authorize?client_id=123456789&scope=read+write&state=123456789123456789
```

レスポンス

```
正常(一例)
    302 Found
        Location：認可画面のURL
```

### 3. 認可画面

アクセストークンと交換するための*認可コード*を取得するエンドポイント ②
![Authorization_code_ground_flow_number (2).png](https://qiita-image-store.s3.amazonaws.com/0/351271/ff351882-456c-db23-0cac-c9b2fbd65a6f.png)
リソースオーナーが認可画面からの WebApp を認可とその認可結果(レスポンス)
リクエスト

```
認可画面からリソースオーナーが行う処理

例)認可ボタンを押す等
```

レスポンス

```
正常
    302 Found
        Location:➀で指定したredirect_uri

        code 必須
            説明：アクセストークンを取得するための短命な認可コード

        state 必須(➀のリクエストに含まれていた場合)
        説明：➀のリクエストに含まれていたそのままの値


異常
    302 Found

    error? 必須(以下いずれかの値)
        invalid_request
            説明：リクエストに必須パラメーターが含まれていない
            　　　リクエストのパラメータ、形式があっていない場合
        unauthorized_client
            説明：クライアント(WebApp)が認可コードを取得することが認められていない場合
        access_denied
            説明：リソースオーナーまたは認可サーバーがリクエストを拒否した場合
        unsupported_response_type
            認可サーバーは現在の方法による認可コード取得をサポートしていない
        invalid_scope
            説明：➀で指定したスコープが不正の場合等
        server_error
            説明：Internal server Error
                リダイレクトした先のWebAppの中でエラーハンドリングするため必要
        temporarily_unavailable
            説明：Service Unavailable
                リダイレクトした先のWebAppの中でエラーハンドリングするため必要
    state
        説明：➀のリクエストに含まれていたそのままの値
    
    error_description 任意
        説明：発生したエラーの詳細

    error_uri 任意 
        説明：エラーに関する追加の情報を得ることができるWebページのURI
    例)
        Location: https://client.example.com/cb?error=access_denied&state=xyz
```

### 4. アクセストークンリクエスト

アクセストークンを取得するためのエンドポイント
クライアント認証が要求されている場合は、Basic認証もしくはリクエストボディーのパラメータを使用して認証を行う
![Authorization_code_ground_flow_number (3).png](https://qiita-image-store.s3.amazonaws.com/0/351271/10054cb3-ceb0-6e99-aea9-05c803fef402.png)

リクエスト

```
POST
    Content-Type: application/x-www-form-urlencoded
    Authorization: Basic Base64URLEncode($client_id:$client_secret)
    説明：Client_idとClient_Secretを使用したクライアントの認証(Basic認証を使用した場合)


grant_type 必須
    値：authorization_code
    説明：認可コードグラントフローであることを示す値

code 必須
    説明：➁で受け取った認可コード

redirect_uri 必須(➀でRedirectURIを含んでいた場合)
    説明：➀でリクエストしたURIと同じであるか検証を行うための値

client_id クライアント認証が要求されているかつ、Basic認証を使用しない場合必須
    説明:クライアントを識別する値

client_secret クライアント認証が要求されているかつ、Basic認証を使用しない場合必須 
    説明:クライアントの認証をする際の鍵

例)
    POST /token HTTP/1.1
    Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
    Content-Type: application/x-www-form-urlencoded

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


```

レスポンス

```
正常
    200 OK

        access_token 必須
            説明：アクセストークン

        token_type 必須
            説明：レスポンスするトークンの種類
            例：Bearer

        expires_in 任意
            説明：アクセストークンの有効秒数

        refresh_token 任意
            説明：リフレッシュトークン
                新しいトークンを取得するためのトークン

        scope 要求したスコープと実際のスコープに差異がある場合は必須
            説明：アクセストークンに付与されている権限

異常
    400 Bad Request (必須)
        invalid_request
            説明：リクエストに必須パラメーターが含まれていない
            　　　リクエストのパラメータ、形式があっていない場合
        invalid_client
            説明：クライアント認証に失敗
        invalid_grant
            説明：不正なリダイレクトURI、不正な認可コード等
        等
```

## 5. まとめ

今回は各エンドポイントの具体的な I/F についてまとめました。
次回(こそ)は認可コードグラントフロー以外のフローについてまとめます。