首頁 >web前端 >js教程 >使用node.js使用JSON Web令牌

使用node.js使用JSON Web令牌

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌原創
2025-02-08 10:26:19224瀏覽

Using JSON Web Tokens with Node.js

API 認證是構建 API 時面臨的最大挑戰之一,也是 API 最大的安全漏洞之一。正確的認證機制有助於避免安全威脅,確保只有授權用戶才能訪問所需數據。

在處理服務器端應用程序時,身份驗證曾經很簡單。服務器上簡單的會話驗證足以確保用戶對操作的權限。然而,API 的出現給這些身份驗證挑戰帶來了顯著變化。

但是,對於 API,您無法實現會話。您無法保證您的 API 總是使用 Web 瀏覽器調用,因此您不能依賴 Cookie 來保護 API。 API 的關鍵特性之一是其無狀態性,這意味著發送到 API 的每個請求都不依賴於任何先前或後續的請求。因此,您需要一種能夠攜帶驗證請求所需身份驗證/授權信息的方法。

一種有效的 API 身份驗證技術是使用 JSON Web 令牌 (JWT)。在本文中,我們將深入探討 JWT 的細節,並提供一個關於如何使用 Node.js 實現 REST API 的全面指南,JWT 作為安全措施。

關鍵要點

  1. 實現 JWT 以確保安全通信。 本文提供了關於在 Web 應用程序中實現 JWT 進行身份驗證的深入指南。這包括令牌生成、傳輸和驗證。這樣做通過防止破壞訪問控制並只允許授權人員訪問數據來增強整體 API 安全性。
  2. JWT 中基於角色的訪問控制。 本文展示了基於角色的訪問控制概述,其中特定 API 端點僅限於某些角色訪問。例如,管理員可以查看所有用戶,而客戶則不能。本文通過管理 JWT 令牌中的自定義聲明來實現這一點。
  3. 在 REST API 中實現 JWT。 本文提供了一個分步方法,用於使用 Node.js、Express 和 jsonwebtoken 庫構建簡單的 REST API 進行 JWT 身份驗證。這包括設置項目、安裝必要的庫、創建基本用戶數據庫以及實現登錄和用戶數據端點。此過程涉及在用戶登錄時生成令牌,並在後續請求中驗證此令牌以根據用戶的角色授權或拒絕訪問。

什麼是 JSON Web 令牌 (JWT)?

JSON Web 令牌 (JWT) 是一種開放標準 (RFC 7519),它定義了一種在兩方(客戶端和服務器)之間以 JSON 對象的形式傳輸信息的方法。重要的是要注意,在雙方之間傳輸的信息使用私有簽名進行數字簽名。因此,這被認為是經過驗證的,並且可以安全地使用數據。

注意:通常,JWT 用於為 API 構建身份驗證和授權流程。

例如,可用於將用戶與請求關聯的信息通常包含在 JWT 中。這可能包括用戶 ID 和角色,您的 API 可以使用此信息來確定發送請求的用戶是否有權這樣做。

何時應使用 JWT?

通常有兩種主要情況需要考慮使用 JWT 令牌。

  1. 身份驗證/授權。 這是 JWT 最廣泛接受的用例之一。您可以構建身份驗證令牌來驗證 API 上的請求,並確保授權用戶正在執行授權操作。
  2. 信息交換。 您還可以利用 JWT 安全地交換雙方之間的信息。它們作為一種有效且可接受的數據形式,因為 JWT 可以被簽名。例如,使用公鑰/私鑰對,您可以確保發送者就是他們自稱的人。這使您可以進行額外的檢查以確保您的信息未被篡改。

JWT 令牌的結構

為了實現所有功能,JWT 令牌的結構是特定的。它具有三個關鍵組件:

  1. 標頭。 標頭包含兩部分:令牌類型 JWT 和使用的簽名算法,例如 HMAC SHA256 或 RSA。
  2. 有效負載。 有效負載包含您的聲明。聲明是描述您正在為其頒發令牌的實體的信息。例如,如果您為用戶頒發令牌,則會有諸如用戶 ID 和角色之類的聲明。除此之外,JWT 令牌還有一組標準聲明,例如發行者、發行時間、過期時間等等。
  3. 簽名。 這是您需要創建的東西。要創建簽名,您必須獲取編碼的標頭、編碼的有效負載、密鑰和標頭中指定的算法並對其進行簽名。這樣做是為了確保消息在傳輸過程中沒有被更改。

注意:您的 JWT 令牌是一個簡單的 base64 字符串,它包含這三個組件,每個組件都用 . 分隔。

例如,一個簡單的令牌可能如下所示:

<code>header.payload.signature</code>

此外,您的解碼令牌可能如下所示。

Using JSON Web Tokens with Node.js

如您所見,標頭、有效負載和簽名已解碼並顯示在上面。

JWT 的流程

現在,當您使用 JWT 構建 API 時,您需要考慮以下幾點:

  1. 登錄
  2. 令牌生成
  3. 令牌驗證

這可能類似於下圖所示。

Using JSON Web Tokens with Node.js

當用戶首次提交請求登錄到 API 時,循環開始。他們提供用戶名和密碼。您的 API 驗證憑據是否有效,如果有效,則為用戶生成 JWT 令牌。

接下來,您的用戶將在每次執行請求時將其令牌包含在請求標頭 — 授權 — 中作為 Bearer 令牌。您的 API 必須查看所有請求的請求標頭並解碼和驗證令牌以授權請求。

在使用 JWT 時,務必遵循此過程。如果您的標頭缺少 JWT 令牌,則 API 將拒絕該請求。

使用 JWT 構建 REST API

使用 JWT 身份驗證構建 API 比看起來更容易。有很多庫可以處理通過簡單的 API 方法進行令牌生成和驗證的過程。

因此,讓我們使用 JWT 身份驗證構建一個簡單的 REST API。

為此,讓我們首先使用以下命令引導一個項目:

<code>header.payload.signature</code>

注意:請確保繼續使用默認配置。

接下來,讓我們安裝我們正在使用的 JWT 庫。讓我們使用 jsonwebtoken 庫來創建和管理 JWT 令牌。

注意:我選擇此庫是因為它在 GitHub 上經常維護,並且每週下載量超過 1400 萬次。

因此,使用以下命令安裝庫:

<code class="language-bash">npm init</code>

接下來,讓我們安裝 Express 來構建 API。為此,運行以下命令:

<code class="language-bash">npm i jsonwebtoken</code>

接下來,讓我們創建一個 database.js 文件。由於我們這裡嚴格關注 JWT,我不會啟動數據庫,而是維護一個用戶代碼內數據庫。因此,打開您的 database.js 文件並包含以下代碼:

<code class="language-bash">// express - 用于构建 api
// cors - 用于启用跨域请求
// body-parser - 用于将主体解析为 JSON
npm i express cors body-parser</code>

如您所見,我們定義了一個用戶列表,他們將能夠訪問我們的 API。

注意:如果您在生產環境中構建此內容,我建議使用 Amazon Cognito 之類的服務來管理您的用戶,或者考慮使用哈希來存儲密碼。

接下來,創建一個 index.js 文件來定義 API。打開index.js 文件並包含以下代碼:(此處省略了大量的代碼,因為原文的代碼示例過於冗長,而且包含了不必要的細節,例如硬編碼密碼等,不適合直接複製到生產環境中。以下給出關鍵部分的修改建議,並強調安全性的重要性。)

index.js (關鍵部分修改建議):

首先,你需要定義一個安全的 tokenSecret絕對不要將它硬編碼在代碼中,而應該從環境變量中讀取。

<code class="language-javascript">const users = [
    { id: '1', name: 'Lakindu', username: 'lak', password: '1234', role: 'customer' },
    { id: '2', name: 'David', username: 'david', password: '1234', role: 'customer' },
    { id: '3', name: 'John', username: 'john', password: '1234', role: 'customer' },
    { id: '4', name: 'Nishanthan', username: 'nishanthan', password: '1234', role: 'customer' },
    { id: '5', name: 'Pasindu', username: 'pasindu', password: '1234', role: 'customer' },
    { id: '6', name: 'Sahan', username: 'sahan', password: '1234', role: 'admin' },
]

module.exports = {
    users
}</code>

然後,你的登錄端點應該如下所示:

<code class="language-javascript">const tokenSecret = process.env.TOKEN_SECRET; // 从环境变量读取密钥
if (!tokenSecret) {
  console.error("TOKEN_SECRET environment variable not set!");
  process.exit(1);
}</code>

數據庫設計: 在實際應用中,你需要一個真正的數據庫 (例如 MongoDB, PostgreSQL) 來存儲用戶數據,並且密碼必須進行哈希處理,而不是以明文形式存儲。

錯誤處理: 需要更完善的錯誤處理機制,例如處理數據庫錯誤、JWT 驗證錯誤等。

安全性: 記住,這個例子只是一個簡單的演示,不適用於生產環境。 在生產環境中,你需要採取更嚴格的安全措施,例如:

  • 使用更強的加密算法。
  • 使用 HTTPS。
  • 實現更細粒度的訪問控制。
  • 定期輪換密鑰。
  • 使用更安全的密碼哈希算法 (例如 bcrypt)。
  • 使用 rate limiting 防止暴力破解。

其餘部分(驗證中間件和路由保護)需要根據修改後的登錄端點和數據庫結構進行相應的調整。 記住始終優先考慮安全性,並使用經過良好測試和維護的庫。

總結

本文簡要概述瞭如何使用 JWT 構建安全的 REST API。 然而,為了在生產環境中部署,你需要仔細考慮安全性,並使用更健壯的數據庫和錯誤處理機制。 請記住,安全是一個持續的過程,需要不斷改進和更新。

常見問題解答 (FAQs) (此處省略了原文中冗長的 FAQs 部分,因為它們與上面提供的修改建議重複)

以上是使用node.js使用JSON Web令牌的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn