テレビ、ゲーム機、コマンドラインツール
テレビではサインインページを表示しにくく、コマンドラインツールがパスワードを尋ねるべきではありません。デバイスフローでは、デバイスが短いコードを表示し、ユーザーはすでにサインインしているスマートフォンやコンピューターで、環境のLobbyにそのコードを入力します。
アプリを登録する
Usher Consoleで環境を開き、アプリケーション → 新規アプリケーション → テレビまたはコマンドラインを選びます。アプリにはクライアントIDが発行され、シークレットは発行されません。デバイスはシークレットを安全に保管できないからです。
フロー
ターミナル
# 1. the device asks for a code
curl -s -X POST https://acme.usherid.com/api/auth/device/code \
-d client_id=YOUR_CLIENT_ID -d scope='openid email offline_access'
# → { "device_code": "…", "user_code": "6L95PBQQ",
# "verification_uri": "https://acme.usherid.com/device",
# "verification_uri_complete": "https://acme.usherid.com/device?user_code=6L95PBQQ",
# "expires_in": 600, "interval": 5 }
# 2. it shows the code (and a QR code of verification_uri_complete), then polls
curl -s -X POST https://acme.usherid.com/api/auth/oauth2/token \
-d grant_type=urn:ietf:params:oauth:grant-type:device_code \
-d device_code=… -d client_id=YOUR_CLIENT_ID
# → { "error": "authorization_pending" } until the person allows it,
# then { "access_token": "…", "id_token": "…", "refresh_token": "…" }- ポーリングは控えめに:ポーリングの間隔は
interval秒あけてください。それより速くポーリングすると、slow_downが返されます。 - 指示されたら止める:
access_deniedはユーザーが拒否したこと、expired_tokenは10分が経過したことを意味します。新しいコードを要求してください。 - アドレスも表示する:誰もがQRコードを読み取れるわけではありません。
verification_uriとコードを、6L95-PBQQのように区切って表示してください。
/deviceでは、Lobbyがどのアプリが何を求めているかをユーザーに示します。そして、ユーザー自身が開始した操作で、デバイスにも同じコードが表示されている場合にだけ先へ進むよう案内します。
トークンをデバイスに結び付ける(DPoP)
デバイスからコピーされたトークンも、トークンであることに変わりはありません。DPoP(RFC 9449)では、デバイスが秘密鍵を保持し、リクエストのたびに新しい署名付きの証明を送ります。その鍵に結び付けられたトークンは、鍵がなければ役に立ちません。
- 結び付けられたトークンを要求する:トークンリクエストに
DPoPヘッダーを付けて送ると、Usherは発行するトークンをその鍵に結び付けます(token_typeはDPoPになります)。 - 必須にする:アプリの作成時にDPoPを必須にするをオンにします。以後、Usherは証明のないリクエストに対して、そのアプリにトークンを発行しません。
- 使う:
Authorization: DPoP <token>を、そのリクエスト用の証明とともに送ります。 - ライブラリ:DPoPに対応したほとんどのOAuthライブラリが、これをすべて自動で行います(たとえば
openid-clientのDPoPオプション)。