一、前言
JWT(JSON Web Token),是为了在网络环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519)。
JWT不是一个新鲜的东西,网上相关的介绍已经非常多了。不是很了解的可以在网上搜索一下相关信息。
二、源码
三、工作流程
JWT本质来说是一个token。在前后端进行HTTP连接时来进行相应的验证。
1. 博客的后台管理系统发起登录请求,后端服务器校验成功之后,生成JWT认证信息;
2. 前端接收到JWT后进行存储;
3. 前端在之后每次接口调用发起HTTP请求时,会将JWT放到HTTP的headers参数里的authorization中一起发送给后端;
4. 后端接收到请求时会根据JWT中的信息来校验当前发起HTTP请求的用户是否是具有访问权限的,有访问权限时则交给服务器继续处理,没有时则直接返回401错误。
四、实现过程
@H_301_28@1. 登录成功生成JWT说明:以下代码只保留了核心代码,详细代码可在对应文件中查看,下同。
<span style="color: #008000;">//<span style="color: #008000;"> ...
<span style="color: #0000ff;">if (hashedPassword ===<span style="color: #000000;"> hashPassword) {
<span style="color: #008000;">//<span style="color: #008000;"> ...
<span style="color: #008000;">//<span style="color: #008000;"> 用户token
const userToken =<span style="color: #000000;"> {
name: userName,id: results[0<span style="color: #000000;">].id
};
<span style="color: #008000;">//<span style="color: #008000;"> 签发token
const token = jwt.sign(userToken,config.tokenSecret,{ expiresIn: '2h'<span style="color: #000000;"> });
<span style="color: #008000;">//<span style="color: #008000;"> ...
<span style="color: #000000;"> }
<span style="color: #008000;">//<span style="color: #008000;"> ...
}
@H_301_28@2. 添加中间件校验JWT、
<div class="cnblogs_code">
const jwt = require('jsonwebtoken'= require('../config/config'= require('util'=<span style="color: #008000;">/<span style="color: #008000;"><span style="color: #008000;">*/<span style="color: #000000;">
- 判断token是否可用
module.exports = <span style="color: #0000ff;">function<span style="color: #000000;"> () {
<span style="color: #0000ff;">return async <span style="color: #0000ff;">function<span style="color: #000000;"> (ctx,next) {
<span style="color: #0000ff;">try<span style="color: #000000;"> {
<span style="color: #008000;">//<span style="color: #008000;"> 获取jwt
const token =<span style="color: #000000;"> ctx.header.authorization;
<span style="color: #0000ff;">if<span style="color: #000000;"> (token) {
<span style="color: #0000ff;">try<span style="color: #000000;"> {
<span style="color: #008000;">//<span style="color: #008000;"> 解密payload,获取用户名和ID
let payload = await verify(token.split(' ')[1<span style="color: #000000;">],config.tokenSecret);
ctx.user =<span style="color: #000000;"> {
name: payload.name,id: payload.id
};
} <span style="color: #0000ff;">catch<span style="color: #000000;"> (err) {
console.log('token verify fail: '<span style="color: #000000;">,err)
}
}
await next();
} <span style="color: #0000ff;">catch<span style="color: #000000;"> (err) {
<span style="color: #0000ff;">if (err.status === 401<span style="color: #000000;">) {
ctx.status = 401<span style="color: #000000;">;
ctx.body =<span style="color: #000000;"> {
success: 0<span style="color: #000000;">,message: '认证失败'<span style="color: #000000;">
};
} <span style="color: #0000ff;">else<span style="color: #000000;"> {
err.status = 404<span style="color: #000000;">;
ctx.body =<span style="color: #000000;"> {
success: 0<span style="color: #000000;">,message: '404'<span style="color: #000000;">
};
}
}
}
}