メインコンテンツへスキップ
このチュートリアルでは、デバイス認可フローを使用して、入力に制約のあるデバイスから独自のAPIを呼び出します。フローの仕組みやメリットについては、「デバイス認可フロー」を参照してください。
Auth0を使用すると、以下を使ってアプリでデバイス認可フローを簡単に実装できます。

前提条件

このチュートリアルを始める前に:
  • 制限事項(下記)を確認して、デバイス認可フローが実装に適しているかどうかを確認してください。
  • Auth0にアプリケーションを登録します
    • [Application Type(アプリケーションタイプ)] として [Native(ネイティブ)] を選択します。
    • 必要な場合は、[Allowed Web Origins(許可されたWebオリジン)] を設定します。これを使用して、ローカル開発のオリジンとしてlocalhostを許可したり、CORSの対象となるアーキテクチャ(例:HTML5+JS)を持つ特定のTVソフトウェアの許可されたオリジンを設定したりできます。ほとんどのアプリケーションはこの設定は使用しません。
    • [OIDC Conformant(OIDC準拠)] トグルが有効になっていることを確認します。この設定は[Dashboard][Applications(アプリケーション)]>[Application(アプリケーション)]>[Advanced Settings(アプリケーション設定)]>[OAuth] にあります。
    • アプリケーションの [Grant Types(付与タイプ)][Device Code(デバイスコード)] が含まれていることを確認します。詳細については、「付与タイプを更新する」をお読みください。
    • アプリケーションがリフレッシュトークンを使用できるようにするには、アプリケーションの [Grant Types(付与タイプ)][Refresh Token(リフレッシュトークン)] が含まれていることを確認します。詳細については、「付与タイプを更新する」をお読みください。リフレッシュトークンの詳細については、「リフレッシュトークン」をお読みください。
  • アプリケーションに少なくとも次の1つの接続をセットアップして有効にします:データベース接続ソーシャル接続
  • APIをAuth0に登録します
    • APIがリフレッシュトークンを受信して、トークンの有効期限が切れたときに新しいトークンを取得できるようにするには、[Allow Offline Access(オンラインでのアクセスを許可する)] を有効にします。リフレッシュトークンの詳細については、「リフレッシュトークン」をお読みください。
  • デバイスのユーザーコードの設定を構成して、ランダムに生成されたユーザーコードの文字セット、形式、長さを定義します。

手順

  1. デバイスコードの要求(デバイスフロー):ユーザーがデバイスを認可するために使用できるデバイスコードを要求します。
  2. デバイスのアクティベーションの要求(デバイスフロー):ユーザーにノートパソコンまたはスマートフォンを使用してデバイスを認可するよう要求します。
  3. トークンの要求(デバイスフロー):トークンエンドポイントをポーリングし、トークンを要求します。
  4. ユーザーの認可(ブラウザフロー):デバイスがトークンを受け取れるように、ユーザーがデバイスを認可します。
  5. トークンの受け取り(デバイスフロー):ユーザーがデバイスを正常に認可すると、トークを受け取ります。
  6. APIの呼び出し(デバイスフロー):取得したアクセストークンを使ってAPIを呼び出します。
  7. トークンのリフレッシュ(デバイスフロー):既存のトークンが期限切れになったら、リフレッシュトークンを使用して新しいトークンを要求します。
任意:サンプルユースケースを参考にしてください 任意:トラブルシューティング

デバイスコードを要求する

ユーザーがデバイスアプリを起動し、デバイスを認可したい場合は、デバイスコードを取得する必要があります。ユーザーがブラウザベースのデバイスでセッションを開始すると、このコードはそのセッションにバインドされます。 デバイスコードを取得するには、アプリがクライアントIDを含むデバイスコードURLからコードを要求する必要があります。

デバイスコードに対するPOSTの例URL

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}'
デバイスコードのパラメーター
カスタムAPIを呼び出すためのデバイスコードを要求するときは、以下のことにご注意ください。
  • オーディエンスパラメーターを含めなければなりません
  • ターゲットAPIによってサポートされている追加のスコープを含めなければなりません
アプリで、認証されたユーザーに関する情報の取得にアクセストークンのみが必要な場合は、オーディエンスパラメーターは必要ありません。
パラメーター名説明
client_idアプリケーションのクライアントIDです。この値は[Application Settings(アプリケーション設定)]にあります。
scope認可を要求するスコープです。スペースで区切る必要があります。profileemailなど、ユーザーに関する標準OIDCスコープ名前空間形式に従ったカスタムクレームターゲットAPIがサポートするスコープ(例:read:contacts)を要求できます。IDトークンの取得や、/userinfoエンドポイントを使ってユーザープロファイル情報を取得する際には、openidを含めます。リフレッシュトークンを取得するにはoffline_accessを含めます([API Settings(API設定)]で__[Allow Offline Access(オフラインアクセスを許可する)]__が有効になっていることを確認します)。URLエンコードされている必要があります。
audienceアプリがアクセスするAPIの一意の識別子です。このチュートリアルの前提条件の一環として作成したAPIの[Settings(設定)]タブのIdentifier(識別子) 値を使用します。URLエンコードされている必要があります。

デバイスコードの応答

すべてがうまくいけば、device_codeuser_codeverification_uriexpires_ininterval、およびverification_uri_complete値を含むペイロードを持つHTTP 200応答を受け取ります。
{
  "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をポーリングする間隔(秒)を示します。
テナント設定で、ランダムに生成されるユーザーコードの文字セットや形式、長さを設定することができます。総当たり攻撃を防ぐために、user_codeには以下のような制限が適用されます。長さの下限
  • BASE20:8文字
  • 数字:9文字
長さの上限
  • 20文字(読みやすくするためにハイフンやスペースを区切り文字として使用する場合はそれも含む)
有効期間
  • 15分

デバイスのアクティベーションを要求する

device_codeおよびuser_codeを受け取ったら、ユーザーに、ノートパソコンまたはスマートフォンでverification_uriにアクセスしてuser_codeを入力するよう求める必要があります。
Auth0 Flows Device Authorization Request, sample page showing two activation methods, user_code and QR code
device_codeはユーザーに直接提供するものではないため、ユーザーが混乱しないように、処理中に表示するべきではありません。
CLIをビルドする際は、この手順をスキップし、verification_uri_completeを使って直接ブラウザーを開くことができます。

トークンを要求する

ユーザーがデバイスを有効にするのを待っている間に、トークンURLのポーリングを開始してアクセストークンを要求します。前のステップで抽出したポーリング間隔(interval)を使用して、device_codeとともにトークンURLPOSTする必要があります。 ネットワーク遅延によるエラーを回避するには、最後のポーリング要求の応答を受信してから各間隔のカウントを開始する必要があります。

トークンURLに対するトークンPOST要求の例

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}'
トークン要求のパラメーター
パラメーター名説明
grant_typeこれを”urn:ietf:params:oauth:grant-type:device_code”に設定します。これは、拡張付与タイプ(RFC6749のセクション4.5で定義)です。URLエンコードされている必要があります。
device_codeこのチュートリアルの前のステップで取得されたdevice_code
client_idアプリケーションのクライアントID。この値はアプリケーション設定で確認できます。

トークンの応答

ユーザーがデバイスを認可するのを待っている間に、いくつかの異なるHTTP 4xx応答を受け取る場合があります。
認可待ち
このエラーは、ユーザーの操作を待っている間に表示されます。このチュートリアルの前の手順で推奨されているintervalを使ってポーリングを継続してください。
HTTP/1.1 403 Forbidden
{
  "error": "authorization_pending",
  "error_description": "..."
}
減速
ポーリングが速すぎます。このチュートリアルの前の手順で推奨されている間隔を使ってポーリングしてください。ネットワーク遅延が原因でこのエラーを受け取ることを避けるには、ポーリング要求の応答を受け取ってから間隔をカウントし始めるようにします。
HTTP/1.1 429 Too Many Requests
{
  "error": "slow_down",
  "error_description": "..."
}
有効期限切れのトークン
ユーザーがデバイスをすぐに認可しなかったため、「device_code」の有効期限が切れました。アプリケーションはユーザーにフローの失効を通知して、フローをもう一度始めるように促す必要があります。
expired_tokenエラーは1回だけ返されます。その後、invalid_grantが返されます。お使いのデバイスがポーリングを停止しなければなりません
HTTP/1.1 403 Bad Request
{ 
  "error": "expired_token",
  "error_description": "..."
}
アクセスが拒否されました
最後に、アクセスが拒否された場合は、次のメッセージが表示されます。
HTTP/1.1 403 Forbidden
{
  "error": "access_denied",
  "error_description": "..."
}
これは、以下を含むさまざまな原因で発生します。
  • ユーザーがデバイスの認可を拒否した
  • 認可サーバーがトランザクションを拒否した
  • 構成されたルールによってアクセスが拒否された(詳細については、「Auth0ルール」をお読みください)

ユーザーを認可する

ユーザーはQRコードをスキャンするか、アクティベーションページを開いてユーザーコードを入力します:
Auth0 Flows Device Authorization prompt directing the user to enter the code displayed on their device
確認ページが表示され、ユーザーが正しいデバイスであることを確認します:
Auth0 Flows Device Authorization sample confirmation prompt directing the user to confirm the code
ユーザーがサインインして、トランザクションが完了します。この手順には、以下の1つ以上のプロセスが含まれます。
  • ユーザーを認証する
  • 認証を行うために、ユーザーをIDプロバイダーへリダイレクトする
  • アクティブなセッションをチェックする
  • 事前に同意が得られていない場合、デバイスに対するユーザーの同意を取得する
Auth0 Flows Device Authorization User authorization prompt directing the user to log in with email and password or with Google or another identity
認証と同意が成功すると、確認のプロンプトが表示されます:
Flows - Device Authorization - Congratulations notification for user
この時点で、ユーザーは認証され、デバイスは認可されています。

トークンを受け取る

ユーザーが認証とデバイスの認可を行っている間、デバイスアプリはトークンURLをポーリングしてアクセストークンを要求し続けます。 ユーザーが正常にデバイスの認可を行った場合、access_tokenrefresh_token(任意)、id_token(任意)、token_type、およびexpires_in値を含むペイロードを持つHTTP 200応答を受け取ります。
{
  "access_token":"eyJz93a...k4laUWw",
  "refresh_token":"GEbRxBN...edjnXbL",
  "id_token": "eyJ0XAi...4faeEoQ",
  "token_type":"Bearer",
  "expires_in":86400
}
トークンは、検証してから保存します。操作方法については、「IDトークンの検証」および「アクセストークンを検証する」を参照してください。
アクセストークンは、Auth0 Authentication APIの/userinfoエンドポイントや他のAPIを呼び出すために使用されます(アクセストークンの詳細については、「アクセストークン」を参照してください)。openidスコープを含めた場合にのみ、アクセストークンを使用して/userinfoを呼び出すことができます。独自のAPIを呼び出す場合に、APIがまず実行しなければならいことは、アクセストークンを検証することです。 IDトークンにはデコードして抽出するべきユーザー情報が含まれています(IDトークンの詳細については、「IDトークン」をお読みください)。id_tokenopenidスコープを含めた場合にのみ応答で返されます。 リフレッシュトークンは、トークンの有効期限が切れた後に、新しいアクセストークンまたはIDトークンを取得するために使用されます(リフレッシュトークンの詳細については、「リフレッシュトークン」をお読みください)。refresh_tokenは、offline_accessスコープを含めて、DashboardでAPIの**[Allow Offline Access(オンラインでのアクセスを許可する)]** を有効にした場合にのみ応答で返されます。
リフレッシュトークンは、ユーザーが実質的に永久に認証された状態を維持できるようにするため、安全に保管しなければなりません。

APIを呼び出す

APIを呼び出すには、アプリケーションは、取得したアクセストークンをベアラートークンとしてHTTP要求の認証ヘッダーで渡さなければなりません。
curl --request GET \
  --url https://myapi.com/api \
  --header 'authorization: Bearer ACCESS_TOKEN' \
  --header 'content-type: application/json'

リフレッシュトークン

このチュートリアルに従って次の操作を完了している場合は、すでにリフレッシュトークンを受け取っています。
  • オフラインアクセスを許可するように、APIを構成する。
  • 認可エンドポイントを通じて認証要求を開始するときにoffline_accessスコープを含める。
リフレッシュトークンを使用して新しいアクセストークンを取得できます。通常、ユーザーが新しいアクセストークンを必要とするのは、以前のアクセストークンの有効期限が切れた後、または新しいリソースに初めてアクセスするときだけです。APIを呼び出すたびにエンドポイントを呼び出して新しいアクセストークンを取得するのは良くない慣行であり、Auth0では同じIPから同じトークンを使用して実行できるエンドポイントへの要求の量を制限するレート制限を維持しています。 トークンを更新するには、grant_type=refresh_tokenを使用して、認証APIの/oauth/tokenエンドポイントに対してPOST要求を行います。

トークンURLに対するリフレッシュトークンのPOST要求の例

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}'
リフレッシュトークン要求パラメーター
パラメーター説明
grant_typeこれを”refresh_token”に設定します。
client_idアプリケーションのクライアントIDです。この値は[Application Settings(アプリケーションの設定)]にあります。
client_secretアプリケーションのクライアントシークレットでし。この値は[Application Settings(アプリケーションの設定)]にあります。
refresh_token使用するリフレッシュトークンです。
scope(任意)要求された権限スコープのスペース区切りのリストです。送信されない場合は、元のスコープが使用されます。それ以外の場合は、スコープの数を減らして要求できます。URLエンコードが必要です。

リフレッシュトークンの応答

すべてがうまくいけば、HTTP 200応答がペイロードに新しいaccess_tokenid_token(任意)、秒単位のトークン有効期間(expires_in)、付与されたscopeの値、token_typeを含めて返されます。
{
  "access_token": "eyJ...MoQ",
  "expires_in": 86400,
  "scope": "openid offline_access",
  "id_token": "eyJ...0NE",
  "token_type": "Bearer"
}
トークンは、検証してから保存します。操作方法については、「IDトークンの検証」および「アクセストークンを検証する」を参照してください。

サンプルユースケース

デバイス認可フローの使用を検出する

ルールを使用して、現在のトランザクションがデバイス認可フローを使用しているかを検出できます(ルールの詳細については、「Auth0ルール」をお読みください)。これを行うには、contextオブジェクトのprotocolプロパティを確認します。
function (user, context, callback) {
   if (context.protocol === 'oauth2-device-code') {
      ...
   }
 
   callback(null, user, context);
}

実装例

  • デバイス認可プレイグラウンド
  • AppleTV(Swift):AppleTVからのデバイス認可フローにAuth0を使用できることを示す簡素なアプリケーションです。
  • CLI(Node.js):認可コードフローではなく、デバイス認可フローを使用するCLIの実装例です。CLIではWebサーバーをホストしてポートを待ち受ける必要がない点で大きく異なります。

トラブルシューティング

テナントログは実行されるあらゆるやり取りを記録するため、問題の解決に利用できます。詳細については、「ログ」をお読みください。

エラーコード

コード名前説明
fdeazデバイス認可要求の失敗
fdeacデバイス有効化の失敗
fdeccユーザーがデバイス確認をキャンセル
fede交換の失敗アクセストークンのデバイスコード
sede交換の成功アクセストークンのデバイスコード

制限事項

デバイス認可フローを使用するには、デバイスが次の要件を満たす必要があります。 また、デバイス認可フローでは以下を実行できません: 機密クライアント以外では、Draft 15に完全に対応しています。詳細については、ietf.orgにあるOAuth 2.0 Device Authorization GrantのDraft 15をお読みください。

もっと詳しく

I