在現代Web應用程序中,身份驗證是非常重要的一環。JSON Web Tokens(JWT)是一種廣泛使用的標準格式,用於在兩個實體之間安全地傳遞信息。本文將介紹什麼是JWT,其內部結構如何運作,以及如何在前後端實現JWT的使用。
JWT簡介
JSON Web Token(JWT)是一種開放標準的規範,它定義了一種緊湊且自我包含的方式,用於在其中傳遞聲明(claims)的 JSON對象。這些聲明通常被用來作爲身份驗證或授權過程中的一個組成部分。JWT一般由三部分組成,它們通過點號(.)分隔:
1. Header – 這部分包含了關於JWT元數據的JSON對象,例如使用了什麼加密算法。這個對象會被Base64編碼以形成第一部分。
2. Payload – 這是JWT的第二部分,它包含了實際需要傳輸的數據。它可以分爲三個類別:註冊(Registered) claim names, public (Public)claim names 和私有(Private)claim names。同樣地,這個對象也會被Base64編碼。
3. Signature – 第三部分是通過使用header中聲明的簽名算法(如HMAC SHA256)計算出的字符串哈希值。這有助於確保JWT的真實性,防止篡改。
JWT結構
以下是一個簡化的例子展示了JWT的結構:
xxxxx.yyyyy.zzzzz
其中`xxxxx`對應於頭部(Header),`yyyyy`對應於載荷(Payload),而`zzzzz`則對應於簽名(Signature)。在實際應用中,`zzzzz`可能還會額外加上一次完整的Base64編碼,以便處理URL中的特殊字符。
JWT示例
讓我們來看一個實際的JWT示例。假設我們有一個用戶名爲“Alice”的用戶登錄了一個網站,服務器會返回一個有效的JWT如下所示:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiZmFsc2UifQ.lTjwL8RpDV0sP8h7rEo9hfk-B_eKcNvqg_9ZkH2gWjM
在這個例子中,我們可以看到三個明顯的部分,每個部分都是一個BASE64編碼後的字符串。解碼這三個部分可以得到以下內容:
{ "alg": "HS256", "typ": "JWT"} // Header (base64 decoded)
{ "sub": "alice", "iat": 1516239022 } // Payload (base64 decoded)
// Signature (not base64 decoded for brevity)
請注意,爲了保護敏感數據,簽名部分沒有進行Base64解碼。
在前端添加JWT令牌功能
在前端JavaScript代碼中,一旦接收到服務器的響應並且其中有JWT,我們需要將其存儲在一個安全的區域,比如瀏覽器中的本地存儲或者 Cookies 中。這樣,每次對受保護資源的請求都會自動攜帶JWT,使得客戶端能夠訪問資源。以下是一些基本步驟來設置這個過程:
1. 獲取Token: 從服務器獲取到JWT之後,你可以直接將其放在HTTP響應頭部的Authorization字段中,形式爲`Bearer `。然後,在你的JavaScript代碼中解析出這個值。
2. 存儲Token: 將JWT保存在localStorage或者Cookies中。如果選擇localStorage,需要注意潛在的跨站腳本攻擊(XSS)風險;如果選擇Cookies,則要注意同源政策限制。
3. 發送請求: 在發起任何需要身份驗證的HTTP請求之前,確保將JWT添加到請求的頭部Authorization字段中。例如,可以使用fetch API或者axios庫來實現這一點。
const token = localStorage.getItem('access_token');
const headers = new Headers({ 'Authorization': `Bearer ${token}` });
fetch('/protected/resource', {
method: 'GET',
headers: headers
})
.then(response => response.json())
.then(data => console.log(data));
後端程序
在服務端,你可能會有一箇中間件或者專門的認證模塊來處理傳入請求中的JWT。這裏的一般流程包括:
1. 驗證Token: 對收到的JWT進行校驗,以確保它是有效且未被篡改的。這可能涉及到檢查簽名的正確性,確認JWT是否過期,以及檢查JWT中所包含的信息與數據庫中的記錄相匹配。
2. 提取Claims: 如果JWT通過了所有驗證,那麼可以從JWT中提取所需的信息,通常是用戶ID或者其他標識用戶的 Claim。
3. 處理請求: 根據提取出來的信息決定是否允許當前請求繼續執行,或者拒絕請求並返回相應的錯誤狀態碼和消息。
4. 更新Token: 在某些情況下,你可能需要在JWT到期前刷新一個新的JWT,或者延長現有JWT的有效期。
JWT作爲一種靈活的身份驗證解決方案,可以在前後端間有效地傳遞和使用。理解它的基礎知識對於構建健壯的安全系統至關重要。