> ## 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.

# デバイスフローの有効化

> Authlete を用いたデバイスフロー対応認可サーバーの構成と設定手順について説明されている。

# デバイスフローの有効化

## はじめに

いわゆる「デバイスフロー」は、Web ブラウザ非搭載のデバイスや、文字入力が困難なデバイスが API クライアントとなる場合に、ユーザーの承認に基づいてアクセストークンを発行する認可フローです。[RFC 8628 (OAuth 2.0 Device Authorization Grant)](https://tools.ietf.org/html/rfc8628)
によって定義されています。

本記事では、Authlete を用いたデバイスフロー対応認可サーバーの構成と、Authlete の設定手順について説明します。

> 本機能は Authlete バージョン 2.1 以降にて利用可能です。

## Authlete API を用いた認可サーバーのデバイスフロー対応

認可サーバーがデバイスフローに対応するためには、以下のエンドポイントおよび「検証 URI」の、新設・改修が必要です。これらを実装するための機能を、Authlete は API として提供しています。

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

  * クライアントから受信した「[デバイス認可リクエスト](https://tools.ietf.org/html/rfc8628#section-3.1)
    」を処理
  * Authlete API: [/device/authorization](https://docs.authlete.com/#device-authorization-api)

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

  * クライアントから受信した「[デバイスアクセストークンリクエスト](https://tools.ietf.org/html/rfc8628#section-3.4)
    」を処理
  * Authlete API: [/auth/token](https://docs.authlete.com/#auth-token-api)

* 「検証 URI」

  * [エンドユーザーから提示された “user\_code” を処理](https://tools.ietf.org/html/rfc8628#section-3.3)
    し、必要に応じてユーザー認証・同意確認を実施
  * Authlete API: [/device/verification](https://docs.authlete.com/#device-verification-api)
    , [/device/complete](https://docs.authlete.com/#device-complete-api)

<img alt="enabling-device-flow_1" class="mx-auto d-block" src="https://mintcdn.com/authlete/afj9OD-5-9bkamcq/ja/v2/configuration-reference/endpoints/enabling-device-flow_1.png?fit=max&auto=format&n=afj9OD-5-9bkamcq&q=85&s=a0690cad221cf9191e982b5e32b7e044" width="1482" height="661" data-path="ja/v2/configuration-reference/endpoints/enabling-device-flow_1.png" />

## Authlete の設定

本セクションではデバイスフローに対応するための設定を説明します。Authlete サービスと、同フローを用いるクライアントの、両方の設定が必要です。

## Authlete サービスの設定

管理者コンソールから以下の項目を設定します。

| タブ      | 項目               | 設定内容                                                                                                                                                                                    |
| ------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 認可      | サポートする認可種別       | **DEVICE\_CODE** を有効化                                                                                                                                                                   |
| デバイスフロー | デバイス認可エンドポイント    | デバイス認可エンドポイントの URL<br />例: [https://as.example.com/device\\\_authorization](https://as.example.com/device\\_authorization)                                                              |
| デバイスフロー | 検証 URI           | エンドユーザーに提示する verification\_uri の値<br />例: [https://as.example.com/device](https://as.example.com/device)                                                                                |
| デバイスフロー | プレースホルダー付き検証 URI | エンドユーザーに（一般的には QR コード等を用いて）提示する verification\_uri\_complete の値<br />例: [https://as.example.com/device?user\\\_code=USER\\\_CODE](https://as.example.com/device?user\\_code=USER\\_CODE) |
| デバイスフロー | 検証コード有効期間        | デバイス検証コード (device\_code) とユーザー検証コード (user\_code) の有効期間秒数<br />例: 600                                                                                                                    |
| デバイスフロー | ポーリング間隔          | トークンエンドポイントへのポーリングリクエスト間の最小秒数<br />例: 5                                                                                                                                                 |
| デバイスフロー | ユーザーコード文字セット     | 生成する user\_code の文字セット<br />例: BASE20                                                                                                                                                   |
| デバイスフロー | ユーザーコード長         | 生成する user\_code の文字数<br />例: 8                                                                                                                                                          |

<img alt="enabling-device-flow_2" class="mx-auto d-block" src="https://mintcdn.com/authlete/afj9OD-5-9bkamcq/ja/v2/configuration-reference/endpoints/enabling-device-flow_2.png?fit=max&auto=format&n=afj9OD-5-9bkamcq&q=85&s=e6db89f4a6e06a928be8d13d4fb99b75" width="832" height="399" data-path="ja/v2/configuration-reference/endpoints/enabling-device-flow_2.png" />

<img alt="enabling-device-flow_3" class="mx-auto d-block" src="https://mintcdn.com/authlete/afj9OD-5-9bkamcq/ja/v2/configuration-reference/endpoints/enabling-device-flow_3.png?fit=max&auto=format&n=afj9OD-5-9bkamcq&q=85&s=f239a4859786343b4baf7ed637cc68c3" width="862" height="655" data-path="ja/v2/configuration-reference/endpoints/enabling-device-flow_3.png" />

## クライアントの設定

クライアントアプリ開発者コンソールにアクセスし、以下の項目を設定します。

| タブ   | 項目                       | 設定内容                  |
| ---- | ------------------------ | --------------------- |
| 基本情報 | クライアントタイプ                | **PUBLIC** を選択        |
| 認可   | 認可種別                     | **DEVICE\_CODE** を有効化 |
| 認可   | \[トークンエンドポイント]クライアント認証方式 | **NONE** を選択          |

> 本記事では、デバイスは「[コンフィデンシャルではないクライアント](https://tools.ietf.org/html/rfc8628#section-5.6)
> 」を想定しています。もしデバイスがコンフィデンシャルクライアントである場合には、「クライアントタイプ」および「クライアント認証方式」についてそれぞれ適切な値を選択してください。

<img alt="enabling-device-flow_4" class="mx-auto d-block" src="https://mintcdn.com/authlete/afj9OD-5-9bkamcq/ja/v2/configuration-reference/endpoints/enabling-device-flow_4.png?fit=max&auto=format&n=afj9OD-5-9bkamcq&q=85&s=f596868dce588cb2865db4ca904483a3" width="862" height="857" data-path="ja/v2/configuration-reference/endpoints/enabling-device-flow_4.png" />

<img alt="enabling-device-flow_5" class="mx-auto d-block" src="https://mintcdn.com/authlete/afj9OD-5-9bkamcq/ja/v2/configuration-reference/endpoints/enabling-device-flow_5.png?fit=max&auto=format&n=afj9OD-5-9bkamcq&q=85&s=ce8be5df0f6504dcff317486639e4c30" width="850" height="395" data-path="ja/v2/configuration-reference/endpoints/enabling-device-flow_5.png" />

<img alt="enabling-device-flow_6" class="mx-auto d-block" src="https://mintcdn.com/authlete/afj9OD-5-9bkamcq/ja/v2/configuration-reference/endpoints/enabling-device-flow_6.png?fit=max&auto=format&n=afj9OD-5-9bkamcq&q=85&s=a72a6d941f5e0069a0f5c92ed3c122be" width="819" height="276" data-path="ja/v2/configuration-reference/endpoints/enabling-device-flow_6.png" />

## 実行例

以下は、クライアントからのデバイス認可リクエストを起点に、エンドユーザーから提示された user\_code の検証を行い、クライアントからのトークンリクエストに対して応答する例です。

<img alt="device-flow-2_ja" class="mx-auto d-block" src="https://mintcdn.com/authlete/afj9OD-5-9bkamcq/ja/v2/configuration-reference/endpoints/device-flow-2_ja.png?fit=max&auto=format&n=afj9OD-5-9bkamcq&q=85&s=79b06f3f106988784a1eeb1713d32dc0" width="1920" height="1080" data-path="ja/v2/configuration-reference/endpoints/device-flow-2_ja.png" />

## デバイス認可リクエスト

ここでは、クライアントが認可サーバーに対して以下の「デバイス認可リクエスト」を送信したとします（手順 #2）。（以下の例はいずれも、読みやすさのために折り返しています）

```
POST /device_authorization HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
...
**client_id=...&scope=openid+profile+read**
```

認可サーバーは Authlete の [/device/authorization](https://docs.authlete.com/#device-authorization-api)
にこのリクエストの内容を転送し、処理を依頼します（手順 #3, 4）。

* リクエスト（手順 #3。curl コマンドによる実行例）

```
curl -s -X POST $apiUrl/device/authorization \
   -u $apiKey:$apiSecret \
   -H 'Content-type: application/json' \
   -d '{"parameters": "**client\_id=...&scope=openid+profile+read**"}'
```

* レスポンス（手順 #4）

```
{
  "type": "deviceAuthorizationResponse",
  "resultCode": "A220001",
  "resultMessage":
    "[A220001] The device authorization request was
     processed successfully.",
  "action": "OK",
  **"deviceCode":
    "-jxwQ_7MEdR3SqS86bEg1ONUYdwGmSYjqH8eIBZ1c3U",
  "responseContent":
    "{\"user_code\":\"TXBBPHDZ\",
      \"device_code\":
        \"-jxwQ_7MEdR3SqS86bEg1ONUYdwGmSYjqH8eIBZ1c3U\",
      \"interval\":5,
      \"verification_uri_complete\":
        \"https://as.example.com/device?user_code=TXBBPHDZ\",
      \"verification_uri\":
        \"https://as.example.com/device\",
      \"expires_in\":600}",
  "userCode": "TXBBPHDZ",
  "verificationUri":
    "https://as.example.com/device",
  "verificationUriComplete":
    "https://as.example.com/device?user_code=TXBBPHDZ",**...
}
```

認可サーバーは Authlete から返却された "responseContent" を、デバイス認可レスポンスの内容として、クライアントに返却します（手順 #5。詳細は省略）。

## 「検証 URI」

### user\_code の検証

クライアントは、認可サーバーから返却されたレスポンスに含まれる "device\_code" の値を用いて、認可サーバーに対し、「デバイスアクセストークンリクエスト」を送信します（後述）。

その一方、同じくレスポンスから取得した "user\_code" の値を、認可サーバーの「検証 URI」に提示するよう、エンドユーザーに促します（手順 #6）。

どのように提示するかはクライアントに任されています。以下は、先のレスポンスに含まれる "verification\_uri" の値と共に、エンドユーザーに示す例 ([RFC 8628 の例](https://tools.ietf.org/html/rfc8628#section-3.3)
に加筆) です。

```text theme={null}
+-----------------------------------------------+
|                                               |
|  Using a browser on another device, visit:    |
|  https://as.example.com/device                |
|                                               |
|  And enter the code:                          |
|  TXBBPHDZ                                     |
|                                               |
+-----------------------------------------------+
```

また以下は、同じくレスポンスに含まれる "verification\_uri\_complete" の値を QR コードにエンコードし、エンドユーザーにスキャンしてもらう例 ([RFC 8628 の例](https://tools.ietf.org/html/rfc8628#section-3.3.1)
に加筆) です。

```text theme={null}
+-------------------------------------------------+
|                                                 |
|  Scan the QR code or, using     +------------+  |
|  a browser on another device,   |[_]..  . [_]|  |
|  visit:                         | .  ..   . .|  |
|  https://as.example.com/device  | . .  . ....|  |
|                                 |.   . . .   |  |
|  And enter the code:            |[_]. ... .  |  |
|  TXBBPHDZ                       +------------+  |
|                                                 |
+-------------------------------------------------+
```

なんらかの方法でエンドユーザーから user\_code を受け取った認可サーバーの「検証 URI」では（手順 #7）、Authlete の [/device/verification](https://docs.authlete.com/#device-verification-api)
API に user\_code を転送し、処理を依頼します（手順 #8, 9）。

* リクエスト（手順 #8。curl コマンドによる実行例）

```text theme={null}
curl -s -X POST $apiUrl/device/verification \
    -u $apiKey:$apiSecret \
    -H 'Content-type: application/json' \
    -d '{"userCode":"TXBBPHDZ"}'
```

* レスポンス（手順 #9）

```
{
    "type": "deviceVerificationResponse",
    "resultCode": "A224001",
    "resultMessage": "[A224001] The user code is valid.",
    "action": "VALID",
    "claimNames": [
        ...
    ],
    "clientId": ...,
    "clientName": "Demo Client",
    "scopes": [
        {
            "defaultEntry": false,
            "name": "openid"
        },
        {
            "defaultEntry": false,
            "name": "profile"
        },
        {
            "defaultEntry": false,
            "name": "read"
        }
    ],
    ...
}
```

このレスポンスには、user\_code の値の検証に成功したことの他に、アクセストークンを要求しているクライアントの情報や、どのようなスコープやクレームを求めているかといった情報が含まれています。

認可サーバーはこれらをもとに、エンドユーザーに同意確認を行うことになります。

### 検証完了

必要に応じて認可サーバーは、エンドユーザーを認証し、上記の情報から「どのクライアントがどのようなアクセス権を要求しているか」をエンドユーザーに提示します（手順 #10, 11）。

そしてエンドユーザーのユーザー識別子と、発行するトークンのプロパティ（スコープやクレームなど）が確定した段階で、Authlete の [/device/complete](https://docs.authlete.com/#device-complete-api)
API を呼び出し、処理を依頼します（手順 #12, 13）。

* リクエスト（手順 #12。curl コマンドによる実行例）

```text theme={null}
curl -s -X POST $apiUrl/device/complete
  -u $apiKey:$apiSecret
  -H 'Content-type: application/json'
  -d '{"userCode":"TXBBPHDZ",
       "result":"AUTHORIZED",
       "subject":"testuser01"}'
```

* レスポンス（手順 #13）

```
{
    "type": "deviceCompleteResponse",
    "resultCode": "A241001",
    "resultMessage": "[A241001] The API call was processed successfully.",
    "action": "SUCCESS"
}
```

この後認可サーバーは処理が完了した旨をエンドユーザーに示し、検証処理を終了します（手順 #14）。

## トークンリクエスト

前述の通りクライアントは、 "device\_code" の値を用いて、認可サーバーに対し「デバイスアクセストークンリクエスト」を送信します（手順 #a）。基本的には、user\_code の検証が完了してアクセストークンが取得できるまで、繰り返しリクエストを行います（ポーリングします）。

* リクエスト（手順 #b。curl コマンドによる実行例）

```text theme={null}
curl -s -X POST $apiUrl/auth/token
  -u $apiKey:$apiSecret
  -H 'Content-type: application/json'
  -d '{"parameters":
         "client_id=...
          &grant_type=urn:ietf:params:oauth:grant-type:device_code
          &device_code=-jxwQ_7MEdR3SqS86bEg1ONUYdwGmSYjqH8eIBZ1c3U"}'
```

* レスポンス（手順 #c。user\_code の検証完了前）

```
{
  "type": "tokenResponse",
  "resultCode": "A242307",
  "resultMessage":
    "[A242307] The device authorization request has not been authorized yet.",
  "action": "BAD_REQUEST",
  "grantType": "DEVICE_CODE",
  "responseContent":
    "{\"error_description\":
        \"[A242307] The device authorization request has not been authorized yet.\",
      \"error\":\"authorization_pending\",
      \"error_uri\":\"https://docs.authlete.com/#A242307\"}",
...
}
```

* レスポンス（手順 #c。user\_code の検証完了後）

```text theme={null}
{
  "type": "tokenResponse",
  "resultCode": "A242002",
  "resultMessage": 
    "[A242002] The token request 
     (grant_type=urn:ietf:params:oauth:grant-type:device_code) was processed
     successfully.",
  "accessToken": "ZJHO26vXTC1LIQXm9aYUFnMZd4R599aFA4hLBmH-OlM",
  "action": "OK",
  "clientId": ...,
  "grantType": "DEVICE_CODE",
  "idToken": 
    "eyJhbGciOiJIUzI1NiJ9.
     eyJhdF9oYXNoIjoiZkpNOHhuODlTaVNQVnNsMGFLYnBTQSIsInN1YiI6InRlc3R1
     c2VyMDEiLCJhdWQiOiIxNzIwMTA4MzE2NjE2MSIsImlzcyI6Imh0dHBzOi8vYXV0
     aGxldGUuY29tIiwiZXhwIjoxNTk2NjE5OTk2LCJpYXQiOjE1OTY1MzM1OTZ9.
     OYuGqNbombW_DrSHsm9A07LZWa4UWyV_hSiSAQy-CYI",
  "refreshToken": "sliwK3Oa6Pag1c2aGenZALcGZXAP9cIiIu_zjGIdBCI",
  "responseContent": 
    "{"access_token":"ZJHO26vXTC1LIQXm9aYUFnMZd4R599aFA4hLBmH-OlM",
      "refresh_token":"sliwK3Oa6Pag1c2aGenZALcGZXAP9cIiIu_zjGIdBCI",
      "scope":"openid profile read",
      "id_token":
        "eyJhbGciOiJIUzI1NiJ9.
          eyJhdF9oYXNoIjoiZkpNOHhuODlTaVNQVnNsMGFLYnBTQSIsInN1YiI6InRlc3R1
          c2VyMDEiLCJhdWQiOiIxNzIwMTA4MzE2NjE2MSIsImlzcyI6Imh0dHBzOi8vYXV0
          aGxldGUuY29tIiwiZXhwIjoxNTk2NjE5OTk2LCJpYXQiOjE1OTY1MzM1OTZ9.
          OYuGqNbombW_DrSHsm9A07LZWa4UWyV_hSiSAQy-CYI",
     "token_type":"Bearer",
     "expires_in":3600}",
  "scopes": [
    "openid",
    "profile",
    "read"
  ],
  "subject": "testuser01",
...
}
```

認可サーバーは "responseContent" の値を抽出し、クライアントに返却します（手順 #d）。

## 関連情報

* [**デバイスフロー (OAuth 2.0 Device Authorization Grant)**](https://www.authlete.com/ja/developers/device_flow/)
  では、デバイスフローの概要と、Authlete における同フローの対応について説明しています。
* [**シーケンス図テンプレート**](https://www.authlete.com/ja/resources/templates/sequence-diagrams/)
  を、Authlete を用いたデバイスフローの設計にご活用ください。
* [**Authlete API リファレンス**](https://docs.authlete.com/#device-flow)
  にて、認可サーバーにデバイスフローを実装するための API についての詳細情報を提供しています。
