概要
サービスのマルチデバイス対応をした際に、各デバイスで同じアカウントにログインするのはユーザにとっては非常に手間です。
例えばテレビデバイスに対応した場合にID&パスワードをリモコンで入力させるのはユーザにとって苦痛でしかありません。
なのでサービス側はユーザが苦労なくスムーズにログインできる方法を提供しなくてはいけませんが、一方でセキュリティについても気にする必要があります。
そんなケースの対応方法としてOAuth 2.0 Device Authorization Grantがあるので紹介します。
ユーザの体験
例としてテレビデバイスでログインします。
huluが体験として分かりやすいので実際にやってみます。
ログインしようとする

コードが表示される
QRコードやアクティベーションコードが表示されます。

カメラで読み取る
QRコードをカメラで読み取ります。

Webページに遷移
QRコードのWebページに遷移します。
未ログインの場合
未ログインだとログインするように言われます。

ログイン済みの場合
ログイン済みだとコード入力された状態になります。

これで「視聴機器を有効化」ボタンを押せばログイン完了です。
非常に簡単ですね。
システム
UXのイメージがついたところで、次にシステム側がどうなっているかを理解します。
シーケンス
システムのシーケンスは以下です。

1. 未ログインデバイスでログインリクエスト
リクエストパラメータは以下です。
| パラメータ | 要否 | 説明 |
|---|---|---|
| client_id | 必須 | クライアントID |
| scope | 任意 | 権限のスコープ |
レスポンスパラメータは以下です。
| パラメータ | 要否 | 説明 |
|---|---|---|
| device_code | 必須 | Device Code |
| user_code | 必須 | User Code |
| verification_uri | 必須 | エンドユーザー検証URI |
| verification_uri_complete | 任意 | user_code を含むエンドユーザー検証URI |
| expires_in | 必須 | device_codeとuser_codeの有効期限(秒) |
| interval | 任意 | トークンリクエストのポーリング間隔(秒) |
Authサーバ側はuser_codeとdevice_codeをexpires_inの期限まで紐付けて持つ必要があります。
2. トークンリクエスト(ポーリング)
次にトークンが取得できるまで以下のパラメータを投げ続けます(ポーリング)
| パラメータ | 要否 | 説明 |
|---|---|---|
| grant_type | 必須 | urn:ietf:params:oauth:grant-type:device_codeという固定値 |
| device_code | 必須 | Device Code |
| client_id | 必須 | クライアントID |
Authサーバはuser_codeのチェックが完了するまではauthorization_pendingエラーやslow_downエラーを返し続けます。
3. ログイン済みスマホデバイスにuser_codeを渡す
QRコードなどで読み込んでverification_uriのページに遷移します。
huluのようにuser_codeが入力された状態になるとユーザにとって非常に楽ですね。
4. user_codeをAuthサーバへ
未ログインであればログインを促します。
5. user_code検証
存在するuser_codeか、またexpires_inの期限内かをチェックします。
問題なければログインユーザと紐付けます。
6. ポーリングの完了
5.のチェックが通ればポーリングしていたリクエストのレスポンスとして、ブラウザでログインしていたユーザのアクセストークンが返ります。
7. リソースAPIの利用
アクセストークンを用いて各リソースのAPIを叩くことができます。
セキュリティ対策
この方法の懸念点として、Remote Phishing (Cross-Device Consent Phishing)があります。
発行したQRコードをばらまいて、誰かがちゃんと見ずに承認してくれるのを待ってその人のアカウントにログインしてもらうやり口です。
これの対策としては以下があります。
ユーザ体験での対応
- その QR/コードが “自分のデバイス” で発行されたと気付かせる
- デバイス側に表示されている ユーザコード(6〜8 桁) を、認可ページでも必ず再表示し「一致しているか確認してください」と質問する
- デバイスの正体を示す
- 認可画面に クライアント名・アイコン・デバイス種別・モデル名など を表示し、ユーザが違和感を検知できるようにする
IdP 側のポリシー
- 発行頻度を抑える
- クライアント/IP ごとにユーザコード発行をレートリミット
- トークン自体を持ち出せなくする
- Sender-constrained tokens(DPoP, mTLS, ハードウェア鍵など)で発行し、トークンを“該当デバイスの秘密鍵”とセットでしか使えないようにする
まとめ
マルチデバイス対応した際にユーザがスムーズに各デバイスにログインできる方法としてDevice Authorization Grantを紹介しました。