跳到主要内容

jwt 教程

基础

jwt
  • 用于用户认证;
安装
pnpm add jsonwebtoken
pnpm add --save-dev @types/jsonwebtoken

加密和解密

加密

加密
// jwt.sign(payload, secretOrPrivateKey, [options, callback])
// payload 为加密信息
// secretOrPrivateKey 为加密解密使用的 key
// algorithm 设置加密算法
// expiresIn 设置过期时间, 如 60(s), "2h", "2d"
jwt.sign(
{ foo: "bar" },
privateKey,
{ algorithm: "HS256", expiresIn: 60 },
function (err, token) {
console.log(token); // 加密成功为 token, 反之为 null
console.log(err); // 报错为一个 object, 反之为 null
}
);

解密

解密
// jwt.verify(token, secretOrPublicKey, [options, callback])
// token 为发送 token
// secretOrPrivateKey 为加密解密使用的 key
// algorithm 设置解密算法
jwt.verify(token, privateKey, { algorithm: "HS256" }, function (err, payload) {
console.log(token); // 解密成功为 payload, 反之为 null
console.log(err); // 报错为一个 object, 反之为 null
});

常见错误

TokenExpiredError
  • token 超过有效期限;
jwt.verify(token, "shhhhh", function (err, decoded) {
if (err) {
/*
err = {
name: 'TokenExpiredError',
message: 'jwt expired',
expiredAt: 1408621000
}
*/
}
});
JsonWebTokenError
  • 乱七八糟的报错;
  • 常见 message;
    • invalid token:无效的令牌;
jwt.verify(token, "shhhhh", function (err, decoded) {
if (err) {
/*
err = {
name: 'JsonWebTokenError',
message: 'jwt malformed'
}
*/
}
});

疑难杂症

option 选项
  • option 选项一旦使用必须设置参数,否则报错;
// 报错, expiresIn 必须设置值;
jwt.sign({ foo: "bar" }, privateKey, { expiresIn: undefined });

最佳实践

promise
export const generateToken = (
name: string,
expiresMinutes?: number
): Promise<Error | string> => {
return new Promise((resolve, reject) => {
if (expiresMinutes) {
jwt.sign(
{ name },
jwtKey,
{
expiresIn: expiresMinutes,
},
(err, token) => {
if (err) reject(new Error(StatusCode.TOKEN_GENERATE_FAILED.message));
if (token) resolve(token);
}
);
}
jwt.sign({ name }, jwtKey, {}, (err, token) => {
if (err) reject(new Error(StatusCode.TOKEN_GENERATE_FAILED.message));
if (token) resolve(token);
});
});
};

export const parseToken = (
token: string
): Promise<Error | jwt.JwtPayload | string> => {
return new Promise((resolve, reject) => {
jwt.verify(token, jwtKey, (err, payload) => {
if (err) reject(new Error(StatusCode.TOKEN_PARSE_FAILED.message));
if (payload) resolve(payload);
});
});
};