常見問題

為什麼需要 Refresh Token?

Access Token 會設定時效,只要時間一到,Access Token 就無法再使用。在這個時候,使用者就必須重新向授權伺服器請求授權(通常是 Authorization Code Grant),才能拿到新的 Access Token。

雖然合理,但是在使用者體驗上可能不大好。舉個類似的例子,台灣銀行的登入有效時間通常是五分鐘,過完五分鐘,系統會要求使用者重新認證。目前看到大多數系統的 Access Token 的時效都不是很長,比方說只有 10 分鐘,當然這是為了考量安全性,但使用者每 10 分鐘都要重新授權,勢必會影響使用服務的體驗。

Refresh Token 的應用場景就是在這個時候,它讓應用程式可以不用重新授權,就能換取新的 Access Token。

Refresh Token 時效該如何設計?

參考 OAuth 2.0 Security Best Current Practice 4.14. Refresh Token Protection 文件,它提到 Refresh Token 是需要設定時效的,一樣由場景決定。

但它提到要做一些特殊處理,例如:當 Refresh Token 被重覆使用第二次的時候,授權伺服器必須要把前一次換得的 Refresh Token 失效後,並回覆請求失敗。以下是兩個例子:

  1. 如果是使用者先處理換發 Token,攻擊者後處理,攻擊者會得到失敗的回應,而使用者則會發生 Token 失效,只要重新請求授權即可繼續請求資源。
  2. 如果是攻擊者先處理換發 Token,使用者後處理,使用者會得到失敗的回應,只要重新請求授權即可繼續請求資源。而攻擊者所換發的 Token 會被這個行為觸發失效,然後攻擊者就無法繼續使用 Token 存取資源。

因為授權伺服器無法辨識請求是否合法,因此變通的做法就是如上面所述,當發現有可疑的請求時,就把權限都先收回再說,至少可以限制攻擊者能夠有效請求資源的時間。

Access Token & Refresh Token 會讓人誤以為是 session 的原因?

當 Access Token 或 Refresh Token 被用來作為登入狀態的時候,可能就會跟 Session 的使用情境是類似的,例如:純前端的授權情境。

但事實上,Access Token 的目的是存取資源,Refresh Token 的用途是換發 Access Token,兩個都跟是否登入沒有相關。

OAuth 2.0 和 OpenID Connect 上該如何做會員註冊?

目前這兩者只有規範如何在跨網域的情境下交換資訊,但沒有規範如何做會員註冊,甚至是忘記密碼等功能。這幾個功能目前還是要靠產品設計來達成。

ID Token 是什麼?

ID Token 的格式是 JWT,裡面存有能夠辨識使用者身分的資訊,這是 OpenID Connect 流程最終拿到的結果之一。如果有需要這個資訊,可以在授權請求的 scope 裡,加上 openid 的範圍。

Access Token 也能夠拿到使用者身分的資訊,OpenID Connect 規範中,有定義一個叫 userinfo 的 API,可以使用 Access Token 打這個 API 取得。

Access Token 能夠使用 JWT 嗎?

當想用 JWT 來當 Access Token 的時候,可以參考這份文件

https://www.rfc-editor.org/rfc/rfc9068

Laravel 內建的 Passport 是不是就是同時扮演授權伺服器與資源伺服器的一個實作範例?

是的。

書裡面有提到比隱含授權更安全的實作方法嗎

如果是 SPA 的情境,可以參考 OAuth 2.0 for Browser-Based Apps 文件,目前還是草稿中:

https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps

關鍵在於需要實作 PKCE,其他都是應用程式端需要注意並實作的。