iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0
Software Development

從登入到授權-現代軟體的身分架構指南系列 第 13

Day 13|Device Authorization Grant 擴展機制:沒有瀏覽器也能授權

  • 分享至 

  • xImage
  •  

前言

上一篇 Day 12 談的是 Client Credentials Grant——完全不需要使用者參與的機器對機器(M2M)情境。今天要回到「有使用者」的場景,但使用者手上的裝置不太一樣:智慧電視、遊戲主機、IoT 裝置、CLI 工具⋯⋯這些裝置常常沒有瀏覽器,或是輸入能力很差。OAuth 2.0 針對這種情境定義了 Device Authorization Grant(RFC 8628),俗稱 Device Flow。

今天內容涵蓋

  1. Device Authorization Grant 是什麼、適用場景
  2. 流程總覽:Device Flow + Browser Flow
  3. Device Authorization Request/Response 格式
  4. Device Access Token Request/Response 與輪詢機制
  5. 安全考量

一、什麼是 Device Authorization Grant

RFC 8628 的 Abstract 說得很明楚:這個 Grant 是為了「連上網路,但缺乏瀏覽器、或輸入能力受限到無法在授權流程中輸入文字」的裝置設計的,例如智慧電視、媒體主機、數位相框、印表機。它讓這些裝置上的 OAuth Client,可以透過使用者在「另一台裝置」上的使用者代理(瀏覽器)完成授權。

RFC 8628 §1 也列出了使用這個 Grant 的四個前提條件:

  1. 裝置已經連上網路
  2. 裝置能發出對外的 HTTPS 請求
  3. 裝置能顯示或以其他方式傳達一組 URI 和代碼給使用者,例如顯示網址與 user_code,或提供 QR Code 讓使用者用手機掃描
  4. 使用者擁有一台「次要裝置」(電腦或智慧型手機),可以用來處理這個請求

因此,Device Authorization Grant 主要用於缺乏瀏覽器、或文字輸入能力受限的裝置。若是智慧型手機這類可以正常開啟瀏覽器、接收重新導向的原生 App,通常仍應採用前面介紹過的 Authorization Code + PKCE,而不是改用 Device Flow。

常見的適用場景:

  • Smart TV/機上盒:YouTube、Disney+ 這類服務在電視上顯示一組代碼,要求使用者拿手機或電腦到指定網址輸入代碼完成登入
  • 遊戲主機/無瀏覽器功能的穿戴裝置:例如在遊戲主機或沒有完整瀏覽器功能的手錶上登入服務時,使用者改用手機或電腦完成授權
  • 會議室裝置:Zoom 官方 App 在視訊會議裝置上的登入
  • CLI 工具:GitHub CLI、雲端服務的命令列工具,在終端機環境中安全完成授權,不用自己處理帳密
  • IoT 裝置:印表機、視訊編碼器等沒有螢幕鍵盤的裝置

二、流程總覽:Device Flow + Browser Flow

Device Authorization Grant 其實包含兩條並行的路徑:一條發生在「裝置本身」(Device Flow),另一條發生在使用者的「瀏覽器」(Browser Flow)。裝置會先向 Authorization Server 取得代碼,接著把驗證網址與使用者代碼顯示給使用者;使用者改用手機或電腦完成登入與授權,裝置端則持續輪詢 Token Endpoint,等待授權完成後取得 Access Token。

https://ithelp.ithome.com.tw/upload/images/20260914/20181928JzS3oYxmkV.png

以上圖來看,流程可以拆成十個步驟:

  1. Device Client 請求授權:Device Client 帶著 client_idscope,向 Authorization Server 的 Device Authorization Endpoint 發出請求。
  2. Authorization Server 回傳代碼:Authorization Server 回應 device_codeuser_codeverification_uri,以及有效時間與輪詢間隔等資訊。
  3. 裝置顯示操作指示:Device Client 將 verification_uriuser_code 顯示給使用者,或提供 QR Code,請使用者改用另一台裝置操作。
  4. 使用者開啟驗證頁面:End User 使用手機或電腦的瀏覽器造訪 verification_uri
  5. 輸入使用者代碼:Authorization Server 要求使用者輸入 user_code,用來對應原本那台等待授權的裝置。
  6. 完成登入與同意授權:使用者在瀏覽器中完成登入,並同意 Device Client 要求的授權範圍。
  7. Device Client 輪詢 Token Endpoint:在使用者完成授權前後,Device Client 會依照 interval 指定的輪詢間隔,持續帶著 device_code 向 Token Endpoint 查詢授權是否完成。
  8. Authorization Server 回傳 Token:使用者完成授權後,Authorization Server 在下一次輪詢回應中回傳 Access Token,視設定也可能包含 Refresh Token。
  9. Device Client 呼叫 API:Device Client 帶著 Access Token 呼叫 Resource Server / API,請求存取受保護資源。
  10. Resource Server 回傳資源:Resource Server 驗證 Access Token 後,回傳對應的資料或受保護資源。

整段流程中,裝置與使用者瀏覽器沒有直接的雙向通訊。使用者在瀏覽器端完成「授權確認」;裝置端則透過輪詢 Token Endpoint 得知授權是否完成。這也是它和 Authorization Code Grant 最大的不同:Device Flow 不需要瀏覽器重新導向回原本的裝置。


三、Device Authorization Request/Response:先取得裝置代碼(RFC 8628 §3.1–3.2)

從這一節開始,會把流程中的 HTTP 請求與回應拆開來看。

第一個階段對應流程圖的步驟 1、2。Device Client 會先向 Authorization Server 的 Device Authorization Endpoint 送出請求,要求建立一組本次授權流程使用的代碼:device_code 給裝置端後續輪詢使用,user_code 則顯示給使用者,讓使用者在另一台裝置上完成驗證。

POST /device_authorization HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

client_id=1406020730&scope=example_scope
參數 說明
client_id Device Client 的識別碼,用來讓 Authorization Server 知道是哪一個應用程式在發起 Device Flow。多數 Device Flow 情境下都會帶上這個參數。
scope 選填。用來表示這次授權想取得哪些存取範圍,例如讀取使用者資料、呼叫特定 API 等。

成功時,Authorization Server 回傳 200 OK。這個回應的重點,是把「給裝置用」和「給使用者用」的資訊分開:

{
  "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
  "user_code": "WDJB-MJHT",
  "verification_uri": "https://example.com/device",
  "verification_uri_complete": "https://example.com/device?user_code=WDJB-MJHT",
  "expires_in": 1800,
  "interval": 5
}
欄位 必填 說明
device_code 必填 裝置端使用的代碼,後續會拿去 Token Endpoint 查詢授權結果,不應顯示給使用者
user_code 必填 使用者輸入的代碼,用來把瀏覽器端的授權動作對應回原本那台裝置
verification_uri 必填 使用者要開啟的驗證頁面網址,通常會設計得簡短好記
verification_uri_complete 選填 已經把 user_code 放進網址的版本,適合做成 QR Code,讓使用者掃描後直接進入驗證頁面
expires_in 必填 device_codeuser_code 的有效秒數,過期後需要重新發起流程
interval 選填 Authorization Server 建議的輪詢間隔;如果沒有回傳,Device Client 會使用預設的輪詢間隔

Device Client 拿到 device_code 之後,還不能直接取得 Access Token;它必須等使用者在另一台裝置完成登入與授權,再用 device_code 去 Token Endpoint 查詢結果。


四、輪詢 Token Endpoint:等待使用者完成授權(RFC 8628 §3.4–3.5)

取得 device_code 後,Device Client 接下來要做的事情,是定期向 Token Endpoint 查詢授權結果。

這也是 Device Flow 和 Authorization Code Grant 很大的差異。Authorization Code Grant 會透過瀏覽器的 redirect_uri 把結果導回 Client;但 Device Flow 面對的是 Smart TV、遊戲主機、CLI 或 IoT 裝置,因此改用「輪詢」的方式,主動向 Authorization Server 查詢:使用者完成授權了嗎?可以核發 Access Token 了嗎?

Device Client 輪詢 Token Endpoint 時,grant_type 固定使用 Device Code Grant 的識別值:

urn:ietf:params:oauth:grant-type:device_code

送到 Token Endpoint 的請求通常會包含以下參數:

參數 必填 說明
grant_type 必填 表示這次使用 Device Code Grant,也就是 urn:ietf:params:oauth:grant-type:device_code
device_code 必填 第三節取得的裝置端代碼。Device Client 每次輪詢 Token Endpoint 時都會帶上它,讓 Authorization Server 知道這次查詢是對應到哪一台正在等待授權的裝置。
client_id 必填 Device Client 的識別碼,用來確認是哪個應用程式在查詢授權結果

輪詢時,Device Client 不能無限制地一直送請求。它應該依照回傳的 interval 等待指定秒數後再查詢;如果回應中沒有 interval,就使用預設的 5 秒作為輪詢間隔。例如 interval: 5 代表 Device Client 至少要等 5 秒,才能再次向 Token Endpoint 查詢授權狀態。

在使用者完成授權之前,Device Client 通常還拿不到 Access Token。這時 Token Endpoint 不會直接回傳成功結果,而是用錯誤碼告訴 Client 目前流程進行到哪裡:

錯誤碼 意思
authorization_pending 使用者還沒完成授權,Client 應該依照輪詢間隔繼續等待並再次查詢
slow_down 輪詢頻率太快,之後每次請求的等待時間都要再增加
access_denied 使用者拒絕了這次授權請求,Client 應停止輪詢
expired_token device_code 已過期,Client 應停止輪詢,並讓使用者重新發起流程

只有 authorization_pendingslow_down 代表「流程尚未結束,可以繼續等待」。收到 access_deniedexpired_token 時,Device Client 就不應再繼續輪詢,而是應該停止流程並把結果呈現給使用者。

等使用者在瀏覽器端完成登入與授權後,Authorization Server 會在下一次輪詢時透過 Token Endpoint 回傳 Access Token;視設定不同,也可能一併回傳 Refresh Token。


五、安全設計與潛在風險

Device Authorization Grant 的安全設計,重點是避免使用者在輸入受限、缺乏完整瀏覽器的裝置上直接輸入帳號密碼。它會把登入與同意授權移到手機或電腦的瀏覽器中完成,原本的 Device Client 只負責顯示代碼、等待結果,並在授權完成後透過 Token Endpoint 取得 Access Token。

因此,Device Flow 不是保證「一定安全」,而是透過幾個設計降低風險:

安全設計 作用
不在受限裝置輸入帳密 避免使用者在 Smart TV、遊戲主機、CLI 或 IoT 裝置上直接輸入帳號密碼
使用另一台裝置完成登入 使用者改在手機或電腦的瀏覽器中登入,Authorization Server 仍可套用 MFA、Passkey、SSO 等既有安全機制
device_code 不能直接換 Token Device Client 拿到 device_code 後只能輪詢;必須等使用者完成登入並同意授權,Token Endpoint 才會回傳 Access Token
代碼有有效期限 device_codeuser_code 都有 expires_in,可縮短代碼外洩後能被利用的時間
輪詢頻率受限制 Device Client 必須遵守 interval;如果輪詢太快,Authorization Server 可以用 slow_down 要求放慢
授權結果由 Token Endpoint 回傳 裝置不需要接收瀏覽器重新導向,而是由裝置端主動輪詢 Token Endpoint 取得結果

不過,這些設計只能降低風險,不能消除所有風險。Device Flow 仍然需要注意以下問題:

風險 說明 防護方式
user_code 被暴力猜測 user_code 需要讓人手動輸入,通常不會設計得太長;如果沒有嘗試次數限制,就可能被猜中 提高亂數強度、限制錯誤嘗試次數、縮短有效期限
device_code 外洩 device_code 是裝置輪詢 Token Endpoint 時使用的代碼,不應顯示給使用者或暴露在不安全通道中 僅透過 HTTPS 傳輸、不顯示給使用者、縮短有效期限、限制單次使用
輪詢濫用 Device Client 若不遵守輪詢間隔,可能造成 Token Endpoint 壓力,也可能被用來做大量嘗試 遵守 interval,收到 slow_down 時增加等待時間
Device Code Phishing 攻擊者可以先在自己的裝置上發起 Device Flow,再誘騙使用者到官方驗證頁輸入代碼,讓使用者誤授權攻擊者的裝置 驗證頁面清楚顯示裝置名稱、應用程式與要求的權限,並提醒使用者只輸入自己正在操作的裝置代碼
共用瀏覽器 Session 使用者若在公用電腦上完成登入,可能留下已登入的 Session,讓下一位使用者接續操作 完成流程後提示關閉瀏覽器、避免在公用裝置登入、必要時要求重新驗證

所以,Device Authorization Grant 的安全性取決於 Authorization Server 與 Client 是否正確實作這些限制。比較好的實作會縮短代碼有效期限、限制錯誤嘗試次數、強制使用 HTTPS、限制代碼只能使用一次,並在驗證頁面清楚顯示正在授權的裝置與權限範圍。


小結

Device Authorization Grant 的重點,是讓「不好輸入帳密、也不適合跑完整瀏覽器流程」的裝置,透過另一台裝置完成使用者授權。

這裡最容易混淆的是 user_codedevice_code

  • user_code 是給使用者看的代碼,會顯示在裝置畫面上,讓使用者到另一台裝置的瀏覽器輸入。
  • device_code 是給 Device Client 使用的代碼,不應顯示給使用者;裝置會用它輪詢 Token Endpoint,確認授權是否完成。

因此,Device Flow 並不是讓登入變得「絕對安全」,而是把帳密輸入移到比較適合的瀏覽器環境中處理,再透過短效代碼、輪詢間隔、錯誤限制與使用者確認,降低風險。

下一篇要看的是 JWT Bearer Grant。它和 Device Authorization Grant 不同,不是讓使用者換到另一台裝置完成授權,而是讓 Client 拿一份已簽章的 JWT Assertion,向 Authorization Server 換取 Access Token,常見於企業內部系統或服務對服務的授權場景。


參考資源


上一篇
Day 12|Client Credentials Grant:伺服器對伺服器的授權方式
下一篇
Day 14|JWT Bearer 擴展機制:拿一張簽好的憑證換 Access Token
系列文
從登入到授權-現代軟體的身分架構指南14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言