一、生成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
微信掃一掃
支付寶掃一掃