了解在 OIDC 協議中的刷新令牌、存取令牌和 ID 令牌
OpenID Connect (OIDC) 協議已成為用於身份管理的廣泛採用標準。但你真的理解這些令牌的角色和屬性嗎?
介紹
OpenID Connect Protocol,也稱為 OIDC,已成為為身份管理提供基本框架的廣泛採用標準。它是一個建立在知名 OAuth 2.0 協議之上的身份驗證層。雖然 OAuth 2.0 僅用於資源授權,OIDC 則是標準化和加強客戶端身份驗證的協議,藉由新的 ID 令牌引入。
等等... 在 OAuth 時代,你可能聽說過刷新令牌和存取令牌,現在 OIDC 又有新概念?你真的理解這些令牌之間的區別嗎?
Logto,我們全面的客戶身份和存取管理(CIAM)解決方案,建立在 OIDC 協議之上。 在我們的社群中,用戶最常問的一個問題是:
刷新令牌、存取令牌和 ID 令牌之間有什麼區別?
因此,在本文中,我們將深入探討 OIDC 令牌的關鍵方面,同時闡明 Logto 如何提升整體開發者體驗。
讓我們從一個實際的情境開始
想像一下你正在開發一個典型的客戶端-伺服器應用程式,並且它們通過 RESTful API 相互通訊。你想讓大部分的 API 保持私有,只允許授權的客戶端訪問。然後你可能會有第一個問題:
我需要哪種類型的令牌來保護我的 API?
快速回答是:存取令牌。
在 OIDC 中,每個受保護的 API 被視為一個資源。當客戶端請求 API 資源時,存取令牌是客戶端傳送給伺服器的憑證,通常透過請求標頭傳送。在伺服器端,每當有請求到來時,伺服器只需要驗證來自客戶端的請求是否帶有有效的存取令牌。
然而,你可能會疑惑:如果我的客戶應用程式可以在成功登入後擁有一個有效的存取令牌,並使用存取令牌請求伺服器 API,這不是已經足夠了嗎?為什麼我還需要刷新令牌和 ID 令牌?
的確,這是一個合理的問題,讓我們逐步解釋。
為什麼我們需要刷新令牌?
雖然技術上存取令牌確實滿足了使系統運作的最低要求,但由於安全考量,存取令牌的有效期通常非常短(通常為一小時)。所以想象一下如果我們只有存取令牌,終端用戶每次存取令牌到期時都必須重新身份驗證。對於現代單頁應用程式尤其是移動應用程式而言,頻繁登出是一個相當痛苦的用戶體驗,儘管我們只是在努力保護他們的用戶安全。
因此,我們需要令牌安全性和用戶便利性之間的平衡。這就是為什麼 OIDC 引入了刷新令牌。
為什麼刷新令牌可以有較長的生命週期?
存取令牌用於訪問 API 資源,所以它們的短暫性有助於減少被洩漏或被截取的風險。而另一方面,因為刷新令牌只用於換取新的存取令牌,因此不像存取令牌那樣頻繁使用,因此暴露的風險相對較低。因此,讓刷新令牌擁有較長的有效期是可以接受的。
確保刷新令牌安全
由於刷新令牌也是儲存在客戶端,確保其不被攻擊是具有挑戰性的,特別是對於公共客戶端如單頁應用程式(SPA)而言。
在 Logto 中,刷新令牌有一個自動的輪換機制默認啟用,這意味著授權伺服器將在其符合標準時發出新的刷新令牌:
- 單頁應用程式:被識別為非發送者約束的客戶端,這些應用程式需要刷新令牌輪換。刷新令牌的存活時間(TTL)不能指定。
- 原生應用程式和傳統網頁應用程式:刷新令牌輪換天生啟用,自動在其 TTL 的 70% 時更新。了解更多
雖然你仍然可以選擇在管理控制台的應用細 節頁面停用刷新令牌輪換,但強烈建議保留這一保護措施。
ID 令牌的本質
ID 令牌使客戶端可以獲取基本的用戶信息而無需請求伺服器。
ID 令牌是一個 JSON Web Token (JWT),其中包含用戶聲明如用戶名、電子郵件、頭像圖片等。它由授權伺服器簽發,可以在客戶端離線驗證和解碼。 這對於現代單頁網頁應用程式和移動應用程式尤為有用,客戶端可以緩存 ID 令牌並用來確定用戶的身份認證狀態,這大大改善整體性能和用戶體驗。
同時需要注意的是,ID 令牌不是用於授權訪問受保護資源的;該角色由存取令牌完成。
在 Logto 中,我們也在我們的 SDK 中使用 ID 令牌來幫助確定客戶端的身份認證狀態。例如,在我們的 JS SDK 中,你可以見到:
然而,正如上文提到的,客戶端 SDK 的 isAuthenticated
標誌只是客戶端緩存的狀態。實時身份驗證狀態仍需由伺服器判斷,通過驗證刷新和存取令牌。
我們還在我們的 SDK 中提供了 getUserClaims()
函數來幫助你解碼 ID 令牌並獲取用戶聲明。不過,緩存狀態不會刷新,直到用戶再次登入。
如果你想從 OIDC 伺服器獲取實時的用戶信息,請使用 fetchUserInfo()
。
Logto 的優勢與功能
Logto 嚴格遵循 OIDC 協議,同時為開發者和企業提供額外的功能和優勢:
- 方便 的 SDK:Logto 的 SDK 為你簡化令牌管理。你不必手動存儲刷新令牌和存取令牌。只需每次調用
getAccessToken()
,SDK 都會嘗試重用存儲的存取令牌,或在過期時自動更新。 - 刷新令牌輪換:Logto 強制執行刷新令牌輪換機制,確保你的刷新令牌在被消耗後總是被更新,這降低了被洩漏或被攻陷的風險。雖然你仍可以在管理控制台上停用,但強烈建議保持開啟。
- 優化的性能:藉助 ID 令牌,你總可以在不請求伺服器的情況下獲取基本的用戶信息。利用 Logto SDK 提供的
isAuthenticated
狀態和getIdTokenClaims()
函數來檢查用戶身份驗證狀態並在客戶端解碼用戶聲明。 - 增強的安全性:Logto 使用 HTTPS 和 TLS 強制執行客戶端與授權伺服器之間的安全連接。這保護你的令牌免受未授權第三方的盜竊,並保證系統的安全。
結論
在 OIDC 協議中,刷新令牌、存取令牌和 ID 令牌共同作用以提供安全和無縫的用戶身份驗證。
- 刷新令牌消除用戶干預來獲取新的存取令牌。
- 存取令牌提供授權以訪問受保護的資源。
- ID 令牌在客戶端提供緩存的用戶信息,提升性能。
了解這些令牌的角色和重要性對於在他們的應用中實現 OIDC 認證的開發者至關重要。
選擇 Logto,開發者和企業可以釋放這些 OIDC 功能的全部潛力,集成可靠和安全的身份驗證系統,保護用戶數據並提供無縫的用戶體驗。