使用 OAuth2 refresh token 的好處

初次看到 refresh token, 想說這東西真礙事, 原本 OAuth2 基本的流程已將使用者的密碼和授權分離, 看起來很完美了, 為什麼授權的 access token 之外, 還要多一個 refresh token? 看了 security - Why Does OAuth v2 Have Both Access and Refresh Tokens? 才明白 refresh token 更進一步提升安全性。

access token 解決了:

  • 使用者不需告訴應用程式密碼
  • 使用者可以細分授權項目
  • 使用者可隨時撤消授權

當 access token 外洩的時候, 只要使用者立即撤消授權, 就可以中止傷害, 相較於修改密碼方便許多 (一組密碼可能用在一到多個帳號上, 甚至可能忘了那些帳號使用同一密碼)。

但是為了減少使用者的認證的麻煩, 一個 access token 通常會授權使用很長一段時間 (比方說一個月)。使用者不容易知道什麼時候發出去的 access token 外洩了, 傷害期可能會太長。外洩的原因可能是使用 access token 取存服務時被竊聽破解, 或是在裝置端的應用程式 (PC、smartphone) 存放的 access token 直接外洩。

有沒有辦法可以兼顧減少使用者認證, 又降低 access token 外洩的傷害期呢? 答案是加上 refresh token。設定授權的 access token 在很短的時間內會過期 (如一小時), 然後 client(應用程式) 要用 refresh token + client id + client secret 取得新的 access token。

client 不需要透過使用者就可以取得新的 access token, 不會打擾到使用者。沒有 client secret 的情況下, 單是外洩 access token, 別人用一小段時間後, token 就過期了, 傷害時間很短。

不過要達到上面的好處, client 必須在不同地方存下 refresh token 和 client secret, 偷懶存在同一地方, 一但破台也是一樣。

security - Why Does OAuth v2 Have Both Access and Refresh Tokens? 還有人提供其它回答, 提到 refresh token 有機會減輕認證伺服器的負擔, 不知是意外的副作用, 或是設計之初就有考慮到。愈了解 OAuth2, 愈覺得制定 OAuth2 的人們考慮的真詳細, 提供很彈性的機制讓實作者可自行調整安全的程度、使用者操作的便利性以及伺服器負擔。

Btw, Google 提供 refresh token 的方式還有一點小撇步。使用預設的方式認證時, Google 只有第一次認證時才會傳回 refresh token, 之後重新認證不會再傳回 refresh token。除非使用者到 Google Account 的 Security 分頁取消對 app 的授權, 接著再認證才會再收到 refresh token。或是在認證 URL 的參數加上 approval_prompt=force。詳細的內容寫在 Using OAuth 2.0 for Web Server Applications - Google Accounts Authentication and Authorization — Google Developers:

Important: When your application receives a refresh token, it is important to store that refresh token for future use. If your application loses the refresh token, it will have to re-prompt the user for consent before obtaining another refresh token. If you need to re-prompt the user for consent, include the approval_prompt parameter in the authorization code request, and set the value to force.

留言

  1. 不好意思有個問題請教。
    在使用https://accounts.google.com/o/oauth2/auth這個uri認證以後可以得到authorization code, 然後使用https://accounts.google.com/o/oauth2/token輸入code參數以後可以得到refresh token。我遇到的情況是儲存的refresh token遺失了,在使用https://accounts.google.com/o/oauth2/auth加上approval_prompt=force後確實可以重新產生
    authorization code然後再去取得新的Refresh token。但是連到https://accounts.google.com/o/oauth2/auth會跳出google的認證頁,有辦法不經過https://accounts.google.com/o/oauth2/auth這一頁得到新的refresh token嗎?

    回覆刪除

張貼留言

這個網誌中的熱門文章

(C/C++ ) 如何在 Linux 上使用自行編譯的第三方函式庫

熟悉系統工具好處多多

virtualbox 使用 USB 裝置