使用 JWT 和 Logto 保護你的 Express.js API
學習如何使用 JSON Web Tokens (JWT) 和 Logto 來保護你的 Express.js API 端點。
簡介
在開發 Web 應用程式時,保護你的 API 端點以防止未經授權的訪問是至關重要的。想像一下你正在建立一個線上購物網站,你一定不希望網絡小偷利用你的 API。
假設你已經建立了一個具有使用者身份驗證的 Express.js 應用程式,使用者必須登入後才能執行某些操作。如果沒有,你可以使用 Logto 開始你的旅程。只需幾行程式碼即可建立使用者身份驗證流程。
然而,即使在使用者身份驗證後,你仍面臨各種選擇來保護你的 API 端點。不幸的是,大多數這些選項都有其缺點:
- 基於會話的驗證:將你的 API 連接到會話存儲,這不具可擴展性,也不適合微服務。
- 調用身份驗證服務:這會增加一個額外的網絡呼叫,從而增加延遲和成本。一些身份驗證服務甚至根據 API 呼叫量收費,可能導致高額費用。
在這個教學中,我們將演示如何使用 JSON Web Tokens (JWT) 和 Logto 來強化你的 API 端點。這種方法提供了可擴展性和最低的額外成本。
前提條件
在深入之前,請確保你擁有以下內容:
- 一個 Logto 帳戶。如果你沒有,可以免費註冊。
- 一個需要 API 保護的 Express.js 專案和一個使用該 API 的客戶應用程式。
- 對 JSON Web Token (JWT) 的基本認識。
在 Logto 中定義你的 API 資源
Logto 充分利用了 RFC 8707: OAuth 2.0 的資源指示器 來保護你的 API 端點。這意味著你可以使用實際 URL 定義你的 API 資源。
導航到 Logto 控制台的 "API 資源" 標籤並點擊 "創建 API 資源" 來創建一個新資源。例如,如果你想保護 /api/products
端點,可以使用 URL https://yourdomain.com/api/products
作為標識符。
在你的客戶應用程式中獲取訪問令牌
要繼續下去,你需要將 Logto SDK 整合到你的客戶應用程式中。這個應用程式可能與你的 Express.js 後端不同;例如,你可能有一個 React 應用程式使用 Express.js 作為後端 API 伺服器。
你還需要調整 Logto SDK 配置,通知 Logto 你想在這個授權流程中請求 API 的訪問令牌。以下是一個使用 React 的範例:
一旦使用者透過 Logto 登入,Logto SDK 中的 isAuthenticated
會變為 true
:
現在,你可以使用 getAccessToken
方法為你的 API 獲取訪問令牌:
最後,在向你的 API 發出的請求中使用 Authorization
標頭包含這個訪問令牌:
在你的 API 中驗證訪問令牌
在你的 Express.js 應用程式中,安裝 jose
庫以進行 JWT 驗證:
由於我們使用的是 Bearer 驗證,從 Authorization
標頭中提取訪問令牌:
接著,創建一個中介軟體來驗證訪問令牌:
你現在可以使用這個中介軟體來保護你的 API 端點:
通過這種方法,你不需要在每次請求到達時聯繫 Logto 伺服器。相反,你只需從 Logto 伺服器中獲取一次 JSON Web Key Set (JWKS),然後在本地驗證訪問令牌。
基於角色的訪問控制
到目前為止,我們只檢查了用戶是否通過 Logto 登入。我們仍然不知道使用者是否具有適當的權限來訪問 API 端點。這是因為 Logto 允許任何人為現有 API 資源獲取訪問令牌。
為了解決這個問題,我們可以使用基於角色的訪問控制 (RBAC)。在 Logto 中,你可以定義角色並為其分配權限 。參考這篇教學來學習如何在 Logto 中定義角色和權限。
定義角色和權限後,你可以將 scopes
選項添加到 LogtoProvider
元件:
然後,Logto 只會向用戶發放具有適當範圍的訪問令牌。例如,如果用戶只有 read:products
範圍,訪問令牌只會包含該範圍:
如果用戶同時具有 read:products
和 write:products
範圍,訪問令牌將包含用空格分隔的兩個範圍:
在你的 Express.js 應用程式中,你可以在授予對 API 端點的訪問權限之前,驗證訪問令牌是否包含正確的範圍:
結論
在確保可擴展性的同時保護 API 端點並不是一件簡單的事情。Logto 致力於簡化開發人員的請求身份驗證,使你能更專注於商業邏輯。
如有任何問題,歡迎加入我們的 Discord 伺服器。我們的社群隨時樂意為你提供幫助。