一、生成Token演算法
Token(令牌)生成是一種驗證用戶身份的方法,通常用於保證API介面的安全性。Token生成演算法可以採用多種方式,其中JWT(Json Web Token)是廣泛使用的一種。
二、Token生成
Token生成通常分為以下兩個步驟:
1、生成一個含有必要信息的JSON對象,如用戶id、用戶名以及過期時間等。
{ "userId": "123456", "username": "john", "exp": 1627074891 }
2、將JSON對象進行簽名,生成最終的Token字元串,如下所示:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTYiLCJ1c2VybmFtZSI6ImpvaG4iLCJleHAiOjE2MjcwNzQ4OTF9.kSuq7xyQbUXZQNP3AnXlcZxTtCMVJHJGUJQjcBOpP8M
Token中包含了頭部、載荷和簽名三部分。其中,頭部指定了簽名演算法,載荷包含了必要信息,簽名通過頭部和載荷計算而來。
三、生成演算法的步驟是
1、將頭部和載荷進行Base64編碼,並將編碼後的字元串用”.”連接起來,形成一個未簽名的Token字元串。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTYiLCJ1c2VybmFtZSI6ImpvaG4iLCJleHAiOjE2MjcwNzQ4OTF9
2、使用密鑰對未簽名的Token字元串進行簽名。簽名演算法可以採用HMAC-SHA256等。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
3、將簽名結果用”.”連接到未簽名的Token字元串後面,形成最終的Token字元串。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTYiLCJ1c2VybmFtZSI6ImpvaG4iLCJleHAiOjE2MjcwNzQ4OTF9.kSuq7xyQbUXZQNP3AnXlcZxTtCMVJHJGUJQjcBOpP8M
四、服務端Token生成演算法
服務端Token生成演算法通常採用JWT。
在實現服務端Token生成演算法時,需要定義Token的有效期、密鑰以及加密方式等參數,如下所示:
const jwt = require('jsonwebtoken') const secret = 'my_secret_key' const expiresIn = '2h' function generateToken(payload) { const token = jwt.sign(payload, secret, { expiresIn }) return token }
以上實現了一個簡單的Token生成方法,通過傳遞payload參數即可生成Token字元串。
五、登錄Token生成演算法
登錄Token生成演算法是指在用戶登錄成功後,生成一個Token用於驗證用戶身份。
登錄Token生成演算法通常包含以下步驟:
1、驗證用戶身份,驗證成功後生成一個JSON對象,包含用戶id、用戶名以及過期時間等信息。
const user = { userId: '123456', username: 'john', exp: Math.floor(Date.now() / 1000) + (60 * 60) }
2、將JSON對象轉換成Token字元串,並返回給客戶端。
const token = generateToken(user) res.json({token})
六、隨機數生成演算法
隨機數生成演算法通常用於生成密鑰、鹽以及Token中的nonce等。
Node.js內置了crypto模塊,提供了豐富的加密演算法以及隨機數生成方法,如下所示:
const crypto = require('crypto') const secret = crypto.randomBytes(16).toString('hex')
以上代碼使用了crypto.randomBytes方法生成了一個16位元組的隨機數,並將其轉換成了hex字元串。
七、登錄令牌Token生成演算法
登錄令牌Token生成演算法可以用於生成用於用戶身份驗證的Token。
通常採用JWT方式實現,以服務端生成的令牌為例,其生成方法可如下:
const jwt = require('jsonwebtoken') const secret = 'my_secret_key' const expiresIn = '30d' function generateLoginToken(user) { const payload = { subject: user.id, iat: Math.floor(Date.now() / 1000), exp: Math.floor(Date.now() / 1000) + (60 * 60 * 24 * 30), alg: 'HS256' } const options = { expiresIn: expiresIn } const token = jwt.sign(payload, secret, options) return token }
八、Token生成原理
Token生成原理是採用了JWT規範,由頭部、載荷以及簽名三部分構成,經過base64編碼形成Token字元串。
其中,Payload中保存了用戶信息、過期時間等數據,用於驗證用戶身份。
簽名則是通過加密演算法將頭部和載荷計算出的簽名值,用於保證Token在傳輸過程中不被篡改。
九、Token簽名演算法
Token簽名演算法通常採用HMAC-SHA256等加密演算法,用於對Token進行加密。
const crypto = require('crypto') function sign(payload, secret) { const header = { alg: 'HS256', typ: 'JWT' } const encodingHeader = base64UrlEncode(JSON.stringify(header)) const encodingPayload = base64UrlEncode(JSON.stringify(payload)) const signature = crypto.createHmac('sha256', secret).update(encodingHeader + "." + encodingPayload).digest('base64') return encodingHeader + '.' + encodingPayload + '.' + signature }
以上代碼演示了如何使用HMAC-SHA256演算法對Token進行簽名。
十、Token加密演算法
Token加密演算法通常採用AES等演算法,用於保證Token在傳輸中的安全性。
const crypto = require('crypto') function encrypt(text, secret) { const iv = crypto.randomBytes(16) const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(secret), iv) let encrypted = cipher.update(text) encrypted = Buffer.concat([encrypted, cipher.final()]) return iv.toString('hex') + ':' + encrypted.toString('hex') } function decrypt(text, secret) { const parts = text.split(':') const iv = Buffer.from(parts[0], 'hex') const encryptedText = Buffer.from(parts[1], 'hex') const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(secret), iv) let decrypted = decipher.update(encryptedText) decrypted = Buffer.concat([decrypted, decipher.final()]) return decrypted.toString() }
以上代碼實現了AES加密演算法的加密和解密方法。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/240244.html