node服务生成和验证JWToken
# 实现思路
引入
jsonwebtoken
包,这个包用来生成和解密 jwt写一个生成 jwt 的方法,这个方法主要用到登录的接口里,然后将生成的 jwt 返回给前端,让前端在每个请求的 header 里面携带 jwt 信息,这里就不做短期 token 和长期 token 了,直接返回一个有效期一天的 token
/** 生成 JWT 的方法 */
export const generateJWToken = (userInfo) => {
const { user_id, user_type, score } = userInfo;
const JWToken = jwt.sign({ user_id, user_type, score }, CRYPTO_KEY, {
expiresIn: '1d',
});
return JWToken;
};
- 写一个接口的路由拦截,这里通过解析请求的 header 信息里面的 authorization,拿到 JWToken 后进行解密,之后根据解密信息的 score 和接口所需要的最小 score,判断用户是否有请求接口的权限
/** 验证 JWT 并且对用户权限进行校验 */
export const authenticateAndAuthorize = (minScore = 0) => {
return (req, res, next) => {
const authHeader = req.headers.authorization;
if (authHeader) {
const JWToken = authHeader.split(' ')[1];
jwt.verify(JWToken, CRYPTO_KEY, (err, user) => {
if (err) {
return res.send({
error: `令牌已经无效!`,
});
}
req.user = user;
const { score } = req.user;
const hasAuth = Number(score) >= Number(minScore);
if (hasAuth) {
next();
} else {
return res.send({
noAuth: true,
error: `积分不够!该接口需要${minScore}积分呀`,
minScore,
});
}
});
} else {
res.send({
error: `登录状态已失效,请重新登录!`,
});
}
};
};
# 使用示例
- 在接口的路由处添加拦截,设置最小要求的积分数量
router.post(
'/getUserList',
authenticateAndAuthorize(10000),
async (req, res) => {
log(JSON.stringify(req.body));
const queryUserSql = `select * from ${DB_NAME}.user_table where user_type <> "superAdmin" `;
try {
const list = await runSql(queryUserSql);
res.send(list);
} catch (e) {
res.send({
error: '查询接口报错!',
});
}
},
);