萬惡之源:
阿里雲:基於JWT的token認證
有需求需要連接java服務器的API,對接的小夥伴給出的教程如上。
仔細看完大致流程是服務端生成JWK(當然也可以用https://mkjwk.org 在線生成),客户端自行添加載荷和頭加密並簽名生成token用以校驗。
但是文中只提供了java實現(keypair還拼錯了一次),無法作為nodejs的參考。
查看了下如何用nodejs做JWS,很多文章説使用jsonwebtoken可以輕鬆做到,
但是實測組件並不能直接使用上文提供的JWK(json格式),反正我生成的token不能用。
所以,需要先使用crypto提取並轉換密鑰格式,再使用jwt組件。
下面是代碼:
const crypto = require("crypto");
const jwt = require("jsonwebtoken");
//jwt字段具體含義從文心一言獲悉,我本人一竅不通
let jwk = {
"p": "xxxxxxxxxxx",//用於加密的大素數因子
"kty": "RSA",//加密算法
"q": "xxxxxxxxxxx",//生成橢圓曲線公鑰的公鑰
"d": "xxxxxxxxxxx",//私鑰
"e": "AQAB",//指數
"use": "sig",//使用目的
"kid": "xxxxxxxxxxx",//標識符
"qi": "xxxxxxxxxxx",//生成橢圓曲線私鑰的公鑰指數
"dp": "xxxxxxxxxxx",//生成橢圓曲線私鑰的私鑰指數
"alg": "RS256",//加密算法
"dq": "xxxxxxxxxxx",//生成橢圓曲線公鑰的私鑰
"n": "xxxxxxxxxxx"//生成橢圓曲線公鑰的模數
};
//獲取到私鑰
const privateKey = crypto.createPrivateKey({ key: jwk, format: "jwk" }).export({ type: "pkcs1", format: "pem" });
//填寫載荷,這個需要和接收方擬定
const payload = {
"jti": "xxxx",//jwt id 需要提供一個唯一ID
"iat": 1701138864,//簽發時間
"exp": 1701182064,//過期時間
"nbf": 1701138804,//生效時間
"sub": "",//用户
"aud": ""//接收者
}
const token = jwt.sign(payload, privateKey ,{
algorithm:"RS256",
header:{}
});
按上面的文章提示,生成的token可以在https://jwt.io/ 在線校驗合法性。
提示:最好找接收方要一份加密後的token,確定payload需要的字段
PS:舊版本nodejs的crypto組件(此前用的大版本是16)的createPrivateKey可能不支持jwk格式,更新到LTS(20.10.0)後可用