實作一個簡單的客戶端 OIDC SDK
Logto 提供了多種不同平台的 SDK。除了我們的官方 SDK,我們也鼓勵社群的開發者自行創建用戶友好的 SDK。這篇文章將指導你如何建構一個基本的客戶端 OIDC SDK。
介紹
Logto 為我們的開發者和商業團隊提供了一個全面的客戶身份和存取管理 (CIAM) 解決方案。我們提供了一系列即用型的 SDK,適用於不同的平台和應用框架。結合我們的 Logto 雲服務,你可以在幾分鐘內輕鬆地為你的應用建立一個高度安全的用戶授權流程。 作為一家起源於開發者社群的公司,Logto 擁抱並珍視我們的社群互動。除了那些由官方開發的 Logto SDK,我們不斷鼓勵並熱烈歡迎社群開發者透過創建更多元且用戶友好的 SDK,來滿足各種平台和框架的獨特需求。 在這篇文章中,我們將簡要演示如何逐步實作一個 OIDC 標準的認證 SDK。
背景
OpenID Connect (OIDC) 流程是一種基於 OAuth 2.0 框架建立的身份驗證協議,提供身份驗證和單一登入功能。它允許用戶能夠在應用中自行驗證,並安全地獲得授權以進一步存取任何私人資源。請參考 OIDC 規範以獲取更多詳細信息。
工作流程
標準的授權碼流程包含以下步驟:
認證流程
- 用戶發起登入請求: 匿名用戶從公共入口訪問你的應用。試圖進行身份驗證並可能進一步請求存取第三方應用或服務上的保護資源。
- 用戶驗證: 客戶端應用生成認證 URI 並向授權伺服器發送請求,授權伺服器會將用戶導向其登入頁面。用戶使用多種登入方法與登入頁面互動,並由授權伺服器進行身份驗證。
- 處理登入回調: 成功認證後,用戶將被重定向回你的應用,並獲得一個授予的
authorization_code
。此authorization_code
包含所有相關的許可,與認證狀態和請求的授權數據相關聯。 - 令牌交換: 使用從上面的重定向地址提取的
authorization_code
發出令牌交換請求。返回:id_token
:一個數位簽名的 JWT,包含已認證用戶的身份信息。access_token
:一個不透明的access_token
,可用於訪問用戶基本信息端點。refresh_token
:允許用戶持續交換access_token
的憑證令牌
授權流程
- 訪問用戶信息: 為獲取更多用戶信息,應用可以向 UserInfo 端點發出附加請求,使用從初始令牌交換流中獲得的不透明
access_token
。這可以檢索有關用戶的其他詳細信息,例如他們的電子郵件地址或個人資料照片。 - 授予訪問保護資源的權限: 如果需要,應用可以向令牌交換端點發出附加請求,使用
refresh_token
結合resource
和scope
參 數,來獲取一個為用戶訪問目標資源提供的專用access_token
。這個過程會簽發一個 JWT 格式的access_token
,包含訪問保護資源所需的所有授權信息。
實現
我們將遵循一些設計策略,在我們的 @logto/client JavaScript SDK 之內,展示如何為你自己的客戶端應用實作一個簡單的 SDK。請謹記,具體的代碼結構可能會根據你正在使用的客戶端框架而有所不同。隨意選擇任何 Logto 官方 SDK 作為你自己 SDK 專案的範例。
預覽
建構函數
構造函數應接受一個 logtoConfig 作為輸入。這提供了所有必要的配置,你將需要通過此 SDK 建立一個認證連接。
根據你正在使用的平台或框架,你可能需要將一個持久的本地存儲實例傳遞給構造函數。此存儲實例將用於存儲所有與授權相關的令牌和秘密。
初始化用戶認證
在生成認證請求 URL 之前,完成若干準備步驟以確保流程安全是必需的。
從授權伺服器獲取 OIDC 配置
定義一個私有方法 `getOidcConfigs``來從授權伺服器的發現端點提取 OIDC 配置。OIDC 配置響應包含客戶端可以用來與授權伺服器進行互動的所有元數據信息,包括其端點位置和伺服器的功能。(更多詳情請參考 OAuth 授權伺服器元數據規範。)
PKCE 生成器
一個 PKCE (Proof Key for Code Exchange) 驗證流對於所有公開的客戶授權碼交換流至關重要。它減少了 authorization_code 攔截攻擊的風險。因此一個 code_challenge
和 code_verifier
是所有公開客戶應用(如原生應用和 SPA)授權請求所必需的。
根據你正在使用的語言和框架,實作的方法可能不同。請參考 code_challenge 和 code_verifier 規範以獲取詳細定義。
生成狀態參數
在授權流程中,狀態參數 是由客戶端生成的隨機值,包含在由客戶端發送的授權請求中。它作為一個安全措施,防止跨站請求偽造(CSRF)攻擊。
存儲會話過渡信息
有幾個參數需要在用戶認證並被重定向回客戶端後保存在存儲中以供驗證使用。我們將實作一個方法來將這些過渡參數設置到存儲中。
登入
讓我們將以上實現的所有東西封裝起來,定義一個方法生成用戶登入 URL 並將用戶重定向到授權伺服器進行身份驗證。
處理用戶登入回調
在上一節中,我們創建了一個生成用戶認證 URL 的登入方法。此 URL 包含從客戶應用發起認證流程所需的所有參數。該方法將用戶重定向到授權伺服器的登入頁面進行身份驗證。在成功登入後,終端用戶將被重定向回上面提供的 redirect_uri 位置。所有必要的參數將在 redirect_uri 中攜帶 ,以完成後續的令牌交換流。
提取並驗證回調 URL
這個驗證步驟對防止任何形式的偽造授權回調攻擊極為重要。在向授權伺服器發送進一步的碼交換請求前,必須仔細驗證回調 URL。 首先,我們需要從應用存儲中檢索之前存儲的 signInSession 信息。
然後在發出令牌交換請求前,驗證回調 URL 的參數。
- 使用先前存儲的
redirectUri
驗證callbackUri
是否與我們發送的相同。 - 使用先前存儲的
state
驗證返回的 state 是否與我們發送的相同。 - 檢查是否有任何錯誤由授權伺服器返回
- 檢查返回的
authorization_code
是否存在
發送碼交換請求
用戶認證流程的最後步驟是我們將使用返回的 authorization_code
發出令牌交換請求,並獲得所需的授權令牌。有關請求參數定義的更多詳細信息,請參考 令牌交換規範。
- code: 我們從回調 URI 收到的
authorization_code
- clientId: 應用 ID
- redirectUri: 與生成用戶登入 URL 時使用的值相同。
- codeVerifier: PKCE 碼驗證器。類似於 redirectUri,授權伺服器將比較此值與我們先前發送的一個,以確保傳入令牌交換請求的驗證。