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

> 入力が制限されたデバイスからデバイス認可フローを使用して API を呼び出す方法を学びます。

# デバイス認可フローを使用して API を呼び出す

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****マスク済み*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  このチュートリアルでは、デバイス認可フローを使用して、入力機能が制限されたデバイスから独自のAPIを呼び出す方法を説明します。このフローの仕組みや、これを使用すべき理由について詳しくは、[デバイス認可フロー](/ja/docs/get-started/authentication-and-authorization-flow/device-authorization-flow)を参照してください。
</Callout>

Auth0 を使用すると、アプリにデバイス <Tooltip tip="認可フロー: OAuth 2.0 フレームワークで定義された認可グラント（またはワークフロー）。" cta="用語集を見る" href="/ja/docs/glossary?term=Authorization+flow">認可フロー</Tooltip>を簡単に実装できます。使用するものは次のとおりです。

* [Authentication API](https://auth0.com/docs/api/authentication): API を直接呼び出す方法については、このまま読み進めてください。インタラクティブに試すには、[デバイスフロー・プレイグラウンド](https://auth0.github.io/device-flow-playground/)を参照してください。

<div id="prerequisites">
  ## 前提条件
</div>

このチュートリアルを始める前に、以下を確認してください。

* 制限事項 (以下) を確認し、デバイス認可フローが実装に適していることを確認してください。
* [アプリケーションを Auth0 に登録します](/ja/docs/get-started/auth0-overview/create-applications/native-apps)。

  * **Application Type** で **Native** を選択します。
  * 必要に応じて、**Allowed Web Origins** を設定します。これは、ローカル開発時に localhost をオリジンとして許可したり、CORS の制約を受けるアーキテクチャの特定の TV ソフトウェア (例: HTML5 + JS) に対して許可するオリジンを設定したりするために使用できます。ほとんどのアプリケーションでは、この設定は不要です。
  * **OIDC 準拠** トグルが有効になっていることを確認します。この設定は、[Dashboard](https://manage.auth0.com/#) の **Applications > Application > Advanced Settings > OAuth** にあります。
  * アプリケーションの **Grant Types** に **Device Code** が含まれていることを確認します。手順については、[Update Grant Types](/ja/docs/get-started/applications/update-grant-types) を参照してください。
  * アプリケーションでリフレッシュトークンを使用できるようにする場合は、アプリケーションの **Grant Types** に **Refresh Token** が含まれていることを確認します。手順については、[Update Grant Types](/ja/docs/get-started/applications/update-grant-types) を参照してください。リフレッシュトークンの詳細については、[Refresh Tokens](/ja/docs/secure/tokens/refresh-tokens) を参照してください。
* アプリケーションに対して少なくとも 1 つの接続を設定し、有効にします: [データベース接続](/ja/docs/get-started/applications/set-up-database-connections), [ソーシャル接続](/ja/docs/authenticate/identity-providers/social-identity-providers)
* [API を Auth0 に登録します](/ja/docs/get-started/architecture-scenarios/mobile-api/part-2#create-the-api)

  * API が以前のトークンの有効期限が切れた際に新しいトークンを取得できるよう、リフレッシュトークンを受け取れるようにしたい場合は、**Allow Offline Access** を有効にします。リフレッシュトークンの詳細については、[Refresh Tokens](/ja/docs/secure/tokens/refresh-tokens) を参照してください。
* [デバイスユーザーコード設定を構成します](/ja/docs/get-started/tenant-settings/configure-device-user-code-settings)。これにより、ランダムに生成されるユーザーコードの文字セット、形式、長さを定義できます。

<div id="steps">
  ## 手順
</div>

1. [デバイスコードをリクエストする](#request-device-code) (デバイスフロー) : ユーザーがデバイスを認可する際に使用するデバイスコードをリクエストします。
2. [デバイスのアクティベーションをリクエストする](#request-device-activation) (デバイスフロー) : ユーザーに、ラップトップまたはスマートフォンを使用してデバイスを認可するよう求めます。
3. [トークンをリクエストする](#request-tokens) (デバイスフロー) : トークンを取得するために、トークンエンドポイントをポーリングします。
4. [ユーザーを認可する](#authorize-user) (ブラウザフロー) : ユーザーがデバイスを認可し、デバイスがトークンを受け取れるようにします。
5. [トークンを受け取る](#receive-tokens) (デバイスフロー) : ユーザーがデバイスの認可に成功すると、トークンを受け取ります。
6. [API を呼び出す](#call-your-api) (デバイスフロー) : 取得したアクセストークンを使用して API を呼び出します。
7. [トークンを更新する](#refresh-tokens) (デバイスフロー) : 既存のトークンの有効期限が切れたら、リフレッシュトークンを使用して新しいトークンをリクエストします。

任意: [サンプルユースケースを確認する](#sample-use-cases)。

任意: [トラブルシューティング](#troubleshoot)。

<div id="request-device-code">
  ### デバイスコードをリクエストする
</div>

ユーザーがデバイスアプリを起動してそのデバイスを認可しようとする場合は、デバイスコードを取得する必要があります。ユーザーがブラウザーでセッションを開始すると、このコードはそのセッションに関連付けられます。

デバイスコードを取得するには、アプリから [device code URL](https://auth0.com/docs/api/authentication#get-device-code) に対して code をリクエストする必要があります。その際、<Tooltip tip="クライアントID: Auth0 が登録済みリソースに付与する識別値です。" cta="用語集を見る" href="/ja/docs/glossary?term=Client+ID">クライアントID</Tooltip> を含めます。

<div id="example-post-to-device-code-url">
  #### デバイスコード URL への POST の例
</div>

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/device/code' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data 'client_id={yourClientId}' \
    --data 'scope={scope}' \
    --data 'audience={audience}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/device/code");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/x-www-form-urlencoded");
  request.AddParameter("application/x-www-form-urlencoded", "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/oauth/device/code"

  	payload := strings.NewReader("client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D")

  	req, _ := http.NewRequest("POST", url, payload)

  	req.Header.Add("content-type", "application/x-www-form-urlencoded")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse response = Unirest.post("https://{yourDomain}/oauth/device/code")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/device/code',
    headers: {'content-type': 'application/x-www-form-urlencoded'},
    data: {client_id: '{yourClientId}', scope: '{scope}', audience: '{audience}'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/oauth/device/code",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D",
    CURLOPT_HTTPHEADER => [
      "content-type: application/x-www-form-urlencoded"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D"

  headers = { 'content-type': "application/x-www-form-urlencoded" }

  conn.request("POST", "/{yourDomain}/oauth/device/code", payload, headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/oauth/device/code")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Post.new(url)
  request["content-type"] = 'application/x-www-form-urlencoded'
  request.body = "client_id={yourClientId}&scope=%7Bscope%7D&audience=%7Baudience%7D"

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="device-code-parameters">
  ##### デバイスコードのパラメーター
</div>

カスタム API を呼び出すためにデバイスコードをリクエストする場合は、次の点に注意してください。

* <Tooltip tip="オーディエンス: 発行されたトークンの対象者を一意に識別する値です。トークン内では aud という名前で表され、その値には IDトークンの場合はアプリケーション（クライアントID）、アクセストークンの場合は API（API 識別子）の ID が含まれます。" cta="用語集を表示" href="/ja/docs/glossary?term=audience">audience</Tooltip> パラメーターを含める必要があります
* 対象 API でサポートされている追加のスコープを含めることができます

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  認証済みユーザーの情報を取得するためだけにアプリでアクセストークンが必要な場合は、audience パラメーターは不要です。
</Callout>

| パラメーター名     | 説明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `client_id` | アプリケーションのクライアントIDです。この値は [Application Settings](https://manage.auth0.com/#/Applications/\{yourClientId}/settings) で確認できます。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `scope`     | 認可をリクエストする [スコープ](/ja/docs/get-started/apis/scopes) です。各値はスペースで区切る必要があります。`profile` や `email` などのユーザーに関する [標準 OIDC スコープ](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims)、[名前空間形式](/ja/docs/secure/tokens/json-web-tokens/create-custom-claims) に準拠した [カスタムクレーム](/ja/docs/secure/tokens/json-web-tokens/json-web-token-claims#custom-claims)、または [対象 API でサポートされている任意のスコープ](/ja/docs/get-started/apis/scopes/api-scopes) (例: `read:contacts`) をリクエストできます。IDトークンを取得する場合、またはユーザーのユーザープロファイル情報を取得するために [/userinfo エンドポイント](https://auth0.com/docs/api/authentication#user-profile) を使用できるようにする場合は、`openid` を含めてください。リフレッシュトークンを取得するには、`offline_access` を含めます ([API Settings](https://manage.auth0.com/#/apis) で **Allow Offline Access** フィールドが有効になっていることを確認してください) 。この値は URL エンコードする必要があります。 |
| `audience`  | アプリがアクセスする API の一意の識別子です。このチュートリアルの前提条件として作成した API の [Settings](https://manage.auth0.com/#/apis) タブにある **Identifier** の値を使用してください。この値は URL エンコードする必要があります。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

<div id="device-code-response">
  #### デバイスコードのレスポンス
</div>

正常に処理されると、`device_code`、`user_code`、`verification_uri`、`expires_in`、`interval`、`verification_uri_complete` の各値を含むペイロードを含む `HTTP 200` レスポンスを受け取ります。

```json lines theme={null}
{
  "device_code": "Ag_EE...ko1p",
  "user_code": "QTZL-MCBW",
  "verification_uri": "https://accounts.acmetest.org/activate",
  "verification_uri_complete": "https://accounts.acmetest.org/activate?user_code=QTZL-MCBW",
  "expires_in": 900,
  "interval": 5
}
```

* `device_code` はデバイス固有のコードです。ユーザーがブラウザーを利用できるデバイスで `verification_uri` にアクセスすると、このコードがそのセッションに紐付けられます。
* `user_code` には、デバイスを認可するために `verification_uri` で入力するコードが含まれます。
* `verification_uri` には、デバイスを認可するためにユーザーがアクセスするURLが含まれます。
* `verification_uri_complete` には、デバイスを認可するためにユーザーがアクセスする完全なURLが含まれます。これにより、必要に応じてアプリでURLに `user_code` を埋め込めます。
* `expires_in` は、`device_code` と `user_code` の有効期間 (秒) を示します。
* `interval` は、トークンをリクエストするためにアプリがトークンURLをポーリングする間隔 (秒) を示します。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  テナント設定では、[ランダムに生成されるユーザーコードの文字セット、形式、長さを設定](/ja/docs/get-started/tenant-settings/configure-device-user-code-settings)できます。

  総当たり攻撃を防ぐため、`user_code` には次の制限が適用されます。

  **最小長**:

  * BASE20 の文字: 8 文字
  * 数字: 9 文字

  **最大長**:

  * 20 文字 (読みやすくするための区切りとして追加されるハイフンとスペースを含む)

  **有効期限**:

  * 15 分
</Callout>

<div id="request-device-activation">
  ### デバイスのアクティベーションを依頼する
</div>

`device_code` と `user_code` を受け取ったら、ユーザーにノートパソコンまたはスマートフォンで `verification_uri` にアクセスし、`user_code` を入力するよう案内する必要があります。

<Frame>
  <img src="https://mintcdn.com/translations/Dcx0M11uuptU53TX/docs/images/cdy7uua7fh8z/2WzaeNXIYCVduRuzyRd0Sb/cdb4d59b657166d0a9a555a662b9ed63/request-device-activation.png?fit=max&auto=format&n=Dcx0M11uuptU53TX&q=85&s=c452a5b19705d03633ccbfa1247e1fc6" alt="Auth0 Flows のデバイス認可リクエスト。2 つのアクティベーション方法（user_code と QR コード）を示すサンプルページ" width="1986" height="1432" data-path="docs/images/cdy7uua7fh8z/2WzaeNXIYCVduRuzyRd0Sb/cdb4d59b657166d0a9a555a662b9ed63/request-device-activation.png" />
</Frame>

`device_code` はユーザーが直接使用するものではないため、混乱を避けるために、この操作中は表示しないでください。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  CLI を構築している場合は、この手順を省略し、すぐに `verification_uri_complete` でブラウザーを開くこともできます。
</Callout>

<div id="request-tokens">
  ### トークンをリクエストする
</div>

ユーザーがデバイスを有効化するのを待っている間に、<Tooltip tip="アクセストークン: API へのアクセスに使用される認可資格情報で、不透明な文字列または JWT の形式です。" cta="用語集を表示" href="/ja/docs/glossary?term=Access+Token">アクセストークン</Tooltip>を取得するため、トークンURLのポーリングを開始します。前の手順で取得したポーリング間隔 (`interval`) を使用して、`device_code` を送信し、[トークンURL](https://auth0.com/docs/api/authentication#device-auth) に `POST` する必要があります。

ネットワーク遅延によるエラーを避けるため、各間隔の計測は、直前のポーリングリクエストへのレスポンスを受信してから開始してください。

<div id="example-request-token-post-to-token-url">
  #### トークンURLに対してトークンをリクエストするPOSTの例
</div>

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data grant_type=urn:ietf:params:oauth:grant-type:device_code \
    --data 'device_code={yourDeviceCode}' \
    --data 'client_id={yourClientId}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/token");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/x-www-form-urlencoded");
  request.AddParameter("application/x-www-form-urlencoded", "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/oauth/token"

  	payload := strings.NewReader("grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}")

  	req, _ := http.NewRequest("POST", url, payload)

  	req.Header.Add("content-type", "application/x-www-form-urlencoded")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse response = Unirest.post("https://{yourDomain}/oauth/token")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/token',
    headers: {'content-type': 'application/x-www-form-urlencoded'},
    data: new URLSearchParams({
      grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
      device_code: '{yourDeviceCode}',
      client_id: '{yourClientId}'
    })
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/oauth/token",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}",
    CURLOPT_HTTPHEADER => [
      "content-type: application/x-www-form-urlencoded"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}"

  headers = { 'content-type': "application/x-www-form-urlencoded" }

  conn.request("POST", "/{yourDomain}/oauth/token", payload, headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/oauth/token")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Post.new(url)
  request["content-type"] = 'application/x-www-form-urlencoded'
  request.body = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code&device_code=%7ByourDeviceCode%7D&client_id={yourClientId}"

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="token-request-parameters">
  ##### トークンリクエストのパラメーター
</div>

| パラメーター名       | 説明                                                                                                                                                                        |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`  | これを "urn:ietf:params:oauth:grant-type:device\_code" に設定します。これは拡張グラントタイプです ([RFC6749](https://tools.ietf.org/html/rfc6749#section-4.5) のセクション 4.5 で定義) 。なお、URL エンコードが必要です。 |
| `device_code` | このチュートリアルの前の手順で取得した `device_code` です。                                                                                                                                     |
| `client_id`   | アプリケーションのクライアントIDです。この値は [Application Settings](https://manage.auth0.com/#/Applications/\{yourClientId}/settings) で確認できます。                                                |

<div id="token-responses">
  #### トークンのレスポンス
</div>

ユーザーがデバイスを認可するまでの間、`HTTP 4xx` 応答がいくつか返されることがあります。

<div id="authorization-pending">
  ##### 認可保留中
</div>

このエラーは、ユーザーの操作を待っている間に表示されます。このチュートリアルの前の手順で取得した推奨間隔で、ポーリングを続けてください。

```json lines theme={null}
HTTP/1.1 403 Forbidden
{
  "error": "authorization_pending",
  "error_description": "..."
}
```

<div id="slow-down">
  ##### 間隔を空けてください
</div>

ポーリングの間隔が短すぎます。このチュートリアルの前の手順で取得した推奨間隔を使用してください。ネットワーク遅延が原因でこのエラーが発生するのを防ぐには、各間隔の計測を、直前のポーリングリクエストへのレスポンスを受信した後に開始する必要があります。

```json lines theme={null}
HTTP/1.1 429 Too Many Requests
{
  "error": "slow_down",
  "error_description": "..."
}
```

<div id="expired-token">
  ##### 期限切れのトークン
</div>

ユーザーがデバイスをすみやかに承認しなかったため、`device_code` の有効期限が切れています。アプリケーションは、フローの有効期限が切れたことをユーザーに通知し、フローを開始し直すよう促す必要があります。

<Warning>
  `expired_token` エラーは 1 回だけ返され、その後は `invalid_grant` が返されます。デバイスは**必ず**ポーリングを停止する必要があります。
</Warning>

```json lines theme={null}
HTTP/1.1 403 Bad Request
{ 
  "error": "expired_token",
  "error_description": "..."
}
```

<div id="access-denied">
  ##### アクセス拒否
</div>

最後に、アクセスが拒否された場合は、次の内容が返されます。

```json lines theme={null}
HTTP/1.1 403 Forbidden
{
  "error": "access_denied",
  "error_description": "..."
}
```

これは、以下のようなさまざまな理由で発生することがあります。

* ユーザーがデバイスの認可を拒否した
* <Tooltip tip="認可サーバー: ユーザーのアクセス境界の定義に関与する集中型サーバー。たとえば、認可サーバーはユーザーが利用できるデータ、タスク、機能を制御できます。" cta="用語集を表示" href="/ja/docs/glossary?term=authorization+server">認可サーバー</Tooltip>がトランザクションを拒否した
* 設定された Rule によってアクセスが拒否された (詳しくは、[Auth0 Rules](/ja/docs/customize/rules) を参照してください。)

<div id="authorize-user">
  ### ユーザーを認可する
</div>

ユーザーは、QRコードをスキャンするか、アクティベーションページを開いてユーザーコードを入力します。

<Frame>
  <img src="https://mintcdn.com/translations/c0RQ9V0YAcT0-8l5/docs/images/cdy7uua7fh8z/7KRZGb2QcksaEVewXK5bc2/b688b813428f0750ea76b7bcac418bba/enter-user-code__1_.png?fit=max&auto=format&n=c0RQ9V0YAcT0-8l5&q=85&s=e814986a9a1eec7cadb6fea50c646497" alt="デバイスに表示されたコードを入力するようユーザーに案内する Auth0 Flows の デバイス認可 プロンプト" width="390" height="532" data-path="docs/images/cdy7uua7fh8z/7KRZGb2QcksaEVewXK5bc2/b688b813428f0750ea76b7bcac418bba/enter-user-code__1_.png" />
</Frame>

正しいデバイスであることをユーザーに確認してもらうため、確認ページが表示されます。

<Frame>
  <img src="https://mintcdn.com/translations/MV7tE-x71x8RWRES/docs/images/cdy7uua7fh8z/4udH69PJSo20QyK8cwhhtc/193488ee0f689f0724345a40dcdb6478/confirm-device__1_.png?fit=max&auto=format&n=MV7tE-x71x8RWRES&q=85&s=771499858a79702e1084c6551dab7c3e" alt="コードを確認するようユーザーに案内する Auth0 Flows の デバイス認可 確認プロンプトのサンプル" width="394" height="532" data-path="docs/images/cdy7uua7fh8z/4udH69PJSo20QyK8cwhhtc/193488ee0f689f0724345a40dcdb6478/confirm-device__1_.png" />
</Frame>

ユーザーはサインインしてトランザクションを完了します。この手順には、次のプロセスの 1 つ以上が含まれる場合があります。

* ユーザーの認証
* 認証を処理するための、ユーザーの <Tooltip tip="IDプロバイダー（IdP）: デジタルアイデンティティを保存および管理するサービス。" cta="用語集を見る" href="/ja/docs/glossary?term=Identity+Provider">IDプロバイダー</Tooltip> へのリダイレクト
* アクティブな <Tooltip tip="シングルサインオン（SSO）: ユーザーが 1 つのアプリケーションにログインすると、そのユーザーを他のアプリケーションにも自動的にログインさせるサービス。" cta="用語集を見る" href="/ja/docs/glossary?term=SSO">SSO</Tooltip> セッションの確認
* 以前に同意が与えられていない場合の、デバイスに対するユーザー同意の取得

<Frame>
  <img src="https://mintcdn.com/translations/pvjQqAy3EB2TK6NP/docs/images/cdy7uua7fh8z/4UbIdGQMucMhoaXxvFLcki/8c1616d7f28bbd37c253a0145a93a17d/user-auth__1_.png?fit=max&auto=format&n=pvjQqAy3EB2TK6NP&q=85&s=8338c652e72d813a0dcc386af5a97b21" alt="メールアドレスとパスワード、または Google やその他の ID でログインするようユーザーに案内する Auth0 Flows の デバイス認可 ユーザー認可プロンプト" width="317" height="584" data-path="docs/images/cdy7uua7fh8z/4UbIdGQMucMhoaXxvFLcki/8c1616d7f28bbd37c253a0145a93a17d/user-auth__1_.png" />
</Frame>

認証と同意が正常に完了すると、確認プロンプトが表示されます。

<Frame>
  <img src="https://mintcdn.com/translations/c0RQ9V0YAcT0-8l5/docs/images/cdy7uua7fh8z/7ze8nZU4b0q3YOzLQSJ6nJ/48ef5170035a200cebb821c581cec9bb/user-confirmation__1_.png?fit=max&auto=format&n=c0RQ9V0YAcT0-8l5&q=85&s=08d4f09c478a98f6d5b745e7e6b3e1a6" alt="ユーザー向けの Flows - デバイス認可 - Congratulations 通知" width="392" height="536" data-path="docs/images/cdy7uua7fh8z/7ze8nZU4b0q3YOzLQSJ6nJ/48ef5170035a200cebb821c581cec9bb/user-confirmation__1_.png" />
</Frame>

この時点で、ユーザーの認証が完了し、デバイスの認可も完了しています。

<div id="receive-tokens">
  ### トークンの受信
</div>

ユーザーがデバイスの認証と認可を行っている間も、デバイスアプリはアクセストークンを要求するためにトークンURLへのポーリングを継続します。

ユーザーがデバイスを正常に認可すると、`access_token`、`refresh_token` (省略可能) 、`id_token` (省略可能) 、`token_type`、`expires_in` の各値を含むペイロードを伴う `HTTP 200` レスポンスを受信します。

```json lines theme={null}
{
  "access_token":"eyJz93a...k4laUWw",
  "refresh_token":"GEbRxBN...edjnXbL",
  "id_token": "eyJ0XAi...4faeEoQ",
  "token_type":"Bearer",
  "expires_in":86400
}
```

<Warning>
  保存する前に、トークンを検証してください。方法については、[IDトークンを検証する](/ja/docs/secure/tokens/id-tokens/validate-id-tokens) および [アクセストークンを検証する](/ja/docs/secure/tokens/access-tokens/validate-access-tokens) を参照してください。
</Warning>

アクセストークンは、Auth0 Authentication API の [`/userinfo` エンドポイント](https://auth0.com/docs/api/authentication#get-user-info) または別の API を呼び出すために使用します。 (アクセストークンの詳細については、[アクセストークン](/ja/docs/secure/tokens/access-tokens) を参照してください。) `openid` スコープを含めた場合にのみ、アクセストークンを使用して `/userinfo` を呼び出せます。独自の API を呼び出す場合、最初に行う必要があるのは、API で [アクセストークンを検証する](/ja/docs/secure/tokens/access-tokens/validate-access-tokens) ことです。

<Tooltip tip="IDトークン: リソースへのアクセスではなく、クライアント自体のための認証情報です。" cta="用語集を表示" href="/ja/docs/glossary?term=ID+Tokens">IDトークン</Tooltip> には、デコードして取り出す必要があるユーザー情報が含まれています。 (IDトークンの詳細については、[IDトークン](/ja/docs/secure/tokens/id-tokens) を参照してください。) `id_token` は、`openid` スコープを含めた場合にのみレスポンスに含まれます。

<Tooltip tip="リフレッシュトークン: ユーザーに再度ログインさせることなく、新しいアクセストークンを取得するために使用するトークンです。" cta="用語集を表示" href="/ja/docs/glossary?term=Refresh+Tokens">リフレッシュトークン</Tooltip> は、以前のアクセストークンまたは IDトークン の有効期限が切れた後に、新しいアクセストークンまたは IDトークン を取得するために使用されます。 (リフレッシュトークンの詳細については、[リフレッシュトークン](/ja/docs/secure/tokens/refresh-tokens) を参照してください。) `refresh_token` は、`offline_access` スコープを含め、Dashboard で API の **Allow Offline Access** を有効にした場合にのみレスポンスに含まれます。

<Warning>
  リフレッシュトークンを使うと、ユーザーを実質的に無期限に認証済みの状態に保てるため、安全に保管する必要があります。
</Warning>

<div id="call-your-api">
  ### API を呼び出す
</div>

API を呼び出すには、HTTP リクエストの Authorization ヘッダーに、取得したアクセストークンを Bearer トークンとして含める必要があります。

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request GET \
    --url https://myapi.com/api \
    --header 'authorization: Bearer ACCESS_TOKEN' \
    --header 'content-type: application/json'
  ```

  ```csharp C# lines theme={null}
  var client = new RestClient("https://myapi.com/api");
  var request = new RestRequest(Method.GET);
  request.AddHeader("content-type", "application/json");
  request.AddHeader("authorization", "Bearer ACCESS_TOKEN");
  IRestResponse response = client.Execute(request);
  ```

  ```go Go lines expandable theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://myapi.com/api"

  	req, _ := http.NewRequest("GET", url, nil)

  	req.Header.Add("content-type", "application/json")
  	req.Header.Add("authorization", "Bearer ACCESS_TOKEN")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java lines theme={null}
  HttpResponse response = Unirest.get("https://myapi.com/api")
    .header("content-type", "application/json")
    .header("authorization", "Bearer ACCESS_TOKEN")
    .asString();
  ```

  ```javascript Node.JS lines theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://myapi.com/api',
    headers: {'content-type': 'application/json', authorization: 'Bearer ACCESS_TOKEN'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP lines expandable theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://myapi.com/api",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
      "authorization: Bearer ACCESS_TOKEN",
      "content-type: application/json"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python lines theme={null}
  import http.client

  conn = http.client.HTTPSConnection("myapi.com")

  headers = {
      'content-type': "application/json",
      'authorization': "Bearer ACCESS_TOKEN"
      }

  conn.request("GET", "/api", headers=headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby lines theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://myapi.com/api")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Get.new(url)
  request["content-type"] = 'application/json'
  request["authorization"] = 'Bearer ACCESS_TOKEN'

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="refresh-tokens">
  ### リフレッシュトークン
</div>

このチュートリアルに沿って進め、次の項目を完了していれば、すでにリフレッシュトークンを受け取っています。

* オフラインアクセスを許可するように API を設定した
* [認可エンドポイント](https://auth0.com/docs/api/authentication/reference#authorize-application) を介して認証リクエストを開始する際に、`offline_access` スコープを含めた

リフレッシュトークンを使用すると、新しいアクセストークンを取得できます。通常、ユーザーが新しいアクセストークンを必要とするのは、以前のアクセストークンの有効期限が切れた場合か、新しいリソースに初めてアクセスする場合だけです。API を呼び出すたびに新しいアクセストークンを取得するためにエンドポイントを呼び出すのは推奨されません。また、Auth0 ではレート制限が設けられており、同じ IP から同じトークンを使用してそのエンドポイントに送信できるリクエスト数は制限されます。

トークンを更新するには、`grant_type=refresh_token` を使用して、Authentication API の `/oauth/token` エンドポイントに `POST` リクエストを送信します。

<div id="example-refresh-token-post-to-token-url">
  #### トークンURLにリフレッシュトークンをPOSTする例
</div>

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://{yourDomain}/oauth/token' \
    --header 'content-type: application/x-www-form-urlencoded' \
    --data grant_type=refresh_token \
    --data 'client_id={yourClientId}' \
    --data 'client_secret={yourClientSecret}' \
    --data 'refresh_token={yourRefreshToken}'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/oauth/token");
  var request = new RestRequest(Method.POST);
  request.AddHeader("content-type", "application/x-www-form-urlencoded");
  request.AddParameter("application/x-www-form-urlencoded", "grant_type=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%7D", ParameterType.RequestBody);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"strings"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/oauth/token"

  	payload := strings.NewReader("grant_type=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%7D")

  	req, _ := http.NewRequest("POST", url, payload)

  	req.Header.Add("content-type", "application/x-www-form-urlencoded")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse response = Unirest.post("https://{yourDomain}/oauth/token")
    .header("content-type", "application/x-www-form-urlencoded")
    .body("grant_type=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%7D")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'POST',
    url: 'https://{yourDomain}/oauth/token',
    headers: {'content-type': 'application/x-www-form-urlencoded'},
    data: new URLSearchParams({
      grant_type: 'refresh_token',
      client_id: '{yourClientId}',
      client_secret: '{yourClientSecret}',
      refresh_token: '{yourRefreshToken}'
    })
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/oauth/token",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => "grant_type=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%7D",
    CURLOPT_HTTPHEADER => [
      "content-type: application/x-www-form-urlencoded"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  payload = "grant_type=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%7D"

  headers = { 'content-type': "application/x-www-form-urlencoded" }

  conn.request("POST", "/{yourDomain}/oauth/token", payload, headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/oauth/token")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Post.new(url)
  request["content-type"] = 'application/x-www-form-urlencoded'
  request.body = "grant_type=refresh_token&client_id={yourClientId}&client_secret={yourClientSecret}&refresh_token=%7ByourRefreshToken%7D"

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="refresh-token-request-parameters">
  ##### リフレッシュトークンのリクエストパラメーター
</div>

| パラメーター名         | 説明                                                                                                                                 |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`    | `"refresh_token"` に設定します。                                                                                                          |
| `client_id`     | アプリケーションのクライアントIDです。この値は [Application Settings](https://manage.auth0.com/#/Applications/\{yourClientId}/settings) で確認できます。         |
| `client_secret` | アプリケーションのクライアントシークレットです。この値は [Application Settings](https://manage.auth0.com/#/Applications/\{yourClientSecret}/settings) で確認できます。 |
| `refresh_token` | 使用するリフレッシュトークンです。                                                                                                                  |
| `scope`         | (任意) 要求するスコープのスペース区切りリストです。送信しない場合は元のスコープが使用されます。送信した場合は、より限定されたスコープのセットを要求できます。なお、URL エンコードが必要です。                                 |

<div id="refresh-token-response">
  #### リフレッシュトークンのレスポンス
</div>

正常に処理されると、新しい `access_token`、`id_token` (省略可) 、トークンの有効期間 (秒)  (`expires_in`) 、付与された `scope` 値、および `token_type` を含むペイロードとともに、`HTTP 200` レスポンスが返されます。

```json lines theme={null}
{
  "access_token": "eyJ...MoQ",
  "expires_in": 86400,
  "scope": "openid offline_access",
  "id_token": "eyJ...0NE",
  "token_type": "Bearer"
}
```

<Warning>
  保存する前に、トークンを検証してください。方法については、[IDトークンの検証](/ja/docs/secure/tokens/id-tokens/validate-id-tokens)および[アクセストークンの検証](/ja/docs/secure/tokens/access-tokens/validate-access-tokens)を参照してください。
</Warning>

<div id="sample-use-cases">
  ## 使用例
</div>

<div id="detect-device-authorization-flow-use">
  ### デバイス認可フローの使用を検出する
</div>

Rules を使用すると、現在のトランザクションでデバイス認可フローが使われているかどうかを検出できます。 (Rules の詳細については、[Auth0 Rules](/ja/docs/customize/rules) を参照してください。) これを行うには、`context` オブジェクトの `protocol` プロパティを確認します。

```javascript lines theme={null}
function (user, context, callback) {
   if (context.protocol === 'oauth2-device-code') {
      ...
   }
 
   callback(null, user, context);
}
```

<div id="sample-implementations">
  ### サンプル実装
</div>

* [デバイス認可プレイグラウンド](https://auth0.github.io/device-flow-playground/)
* [AppleTV (Swift)](https://github.com/pushpabrol/auth0-device-flow-appletv): AppleTV でデバイス認可フローを使用して Auth0 を利用する方法を示すシンプルなアプリケーションです。
* [CLI (Node.js)](https://gist.github.com/panva/ebaacfe433a8677bdbf458f6e1132045): Authorization Code Flow の代わりにデバイス認可フローを使用する CLI のサンプル実装です。主な違いは、CLI では Web サーバーをホストしてポートで待ち受ける必要がないことです。

<div id="troubleshoot">
  ## トラブルシューティング
</div>

テナントログは、発生したあらゆる操作に対して作成され、問題のトラブルシューティングに利用できます。詳細については、[Logs](/ja/docs/deploy-monitor/logs)を参照してください。

<div id="error-codes">
  ### エラーコード
</div>

| Code    | 名前                  | 説明                  |
| ------- | ------------------- | ------------------- |
| `fdeaz` | デバイス認可リクエストの失敗      |                     |
| `fdeac` | デバイス有効化の失敗          |                     |
| `fdecc` | ユーザーによるデバイス確認のキャンセル |                     |
| `fede`  | 交換の失敗               | デバイスコードをアクセストークンに交換 |
| `sede`  | 交換の成功               | デバイスコードをアクセストークンに交換 |

<div id="limitations">
  ### 制限事項
</div>

デバイス認可フローを使用するには、デバイスが以下の条件を満たしている必要があります。

* [カスタムドメイン](/ja/docs/customize/custom-domains) を使用する場合は、Server Name Indication (SNI) をサポートしていること
* [Auth0 application type](/ja/docs/get-started/applications) が **Native** であること
* [Token Endpoint Authentication Method](/ja/docs/get-started/applications/application-settings) が **None** に設定されていること
* [OIDC-conformant](/ja/docs/get-started/applications/application-settings) であること
* [Dynamic Client Registration](/ja/docs/get-started/applications/dynamic-client-registration) で作成されていないこと

さらに、デバイス認可フローでは以下はサポートされません。

* [Universal Login experience](/ja/docs/authenticate/login/auth0-universal-login/universal-login-vs-classic-login/universal-experience) を使用している場合を除き、[Auth0 developer keys](/ja/docs/authenticate/identity-providers/social-identity-providers/devkeys) を使用する [ソーシャル接続](/ja/docs/authenticate/identity-providers/social-identity-providers)
* ホスト型ログインページ、Rules、または Actions からのクエリ文字列パラメーターへのアクセス
* [ユーザーアカウントのリンク](/ja/docs/manage-users/user-accounts/user-account-linking)

<Tooltip tip="機密クライアント: 信頼できるバックエンドサーバーを使用して認証情報を安全に保持できるクライアント（アプリケーション）です。例としては、安全なバックエンドを備えた Web アプリケーションや、マシン間（M2M）アプリケーションがあります。" cta="用語集を見る" href="/ja/docs/glossary?term=confidential+Clients">confidential Clients</Tooltip> を除き、Draft 15 全体をサポートしています。詳しくは、[ietf.org の OAuth 2.0 Device Authorization Grant Draft 15](https://tools.ietf.org/html/draft-ietf-oauth-device-flow-15) を参照してください。

<div id="learn-more">
  ## 詳細情報
</div>

* [OAuth 2.0 認可フレームワーク](/ja/docs/authenticate/protocols/oauth)
* [OpenID Connect プロトコル](/ja/docs/authenticate/protocols/openid-connect-protocol)
* [トークン](/ja/docs/secure/tokens)
* [ログ](/ja/docs/deploy-monitor/logs)
