JWT原理
token: 当成功登陆之后,后端返回的一个凭据(就是一个长长的字符串),有了这个凭据之后,后续再发请求接口,就可以带上它,就样就可以访问那些“权限接口”
分析
前端:
- 登录成功后,后端会返回token,前端要保存token到localstorage
- 请求 /xxx/xxx接口时,在请求头中加入
Authorization
字段,值为token。
后端:
- 当用户登录时,生成token,再返回给接口
- 收到用户请求接口时,做判断:如果客户端请求的接口是需要做检验的(需要登陆之后才能访问),则要去验证token的真伪
token-登陆成功后端返回token
使用第三方模块 jsonwebtoken 创建token
基本步骤
- 在项目中下载按菜单
npm i jsonwebtoken
- 加载模块
const jwt = require('jsonwebtoken');
- 在用户登陆成功之后,调用 jwt.sign() 方法创建token, 它有如下4个参数:
- 参数1: 必填,对象形式;希望在token中保存的数据
- 参数2:必填,字符串形式;加密的钥匙;后续验证token的时候,还需要使用
- 参数3:可选,对象形式;配置项,比如可以配置token的有效期
- 参数4:可选,函数形式;生成token之后的回调
- 生成的token前面,必须拼接
Bearer
这个字符串
参考代码
const jwt = require('jsonwebtoken');
// 用户登陆方法
app.post('/login', (req, res) => {
// 其它代码......
// 调用生成 token 的方法
const tokenStr = jwt.sign(
{name: 'xxx' },
'beizi',
{ expiresIn: 20 }
);
const token = 'Bearer ' + tokenStr
// 把 token 字符串 返回 给客户端浏览器
// 生成的token前面,必须拼接 Bearer 这个字符串
res.send({ code: 200, msg: '登录成功', token})
})
token-前端保存后端回传的token
// 保存从后端传回的token
localStorage.setItem('token', res.token)
token-ajax请求携带token
// 按照规范请求头传递 Authorization
// 在发请求时,带上token
headers:{
Authorization: localStorage.getItem('token')
},
token-后端代码实现token认证
选择使用 express-jwt 第三方模块进行身份认证。从模块名可以看出,该模块是专门配合express使用的。
下载安装
npm i express-jwt
中间件技术-验证token
const jwt = require('express-jwt');
// app.use(jwt().unless());
// jwt() 用于解析token,并将 token 中保存的数据 赋值给 req.user
// unless() 约定某个接口不需要身份认证
app.use(jwt({
secret: 'beizi', // 生成token时的 钥匙,必须统一
algorithms: ['HS256'] // 必填,加密算法,无需了解
}).unless({
path: ['/user/login', '/user/register'] // 除了这两个接口,其他都需要认证
}));
当一个接口请求到了服务器后,它会自动验证请求头中的 Authorization字段:
- 如果没有问题
- 将token中保存的 数据 赋值给 req.user
- next()
- 有问题则抛出错误 next(错误信息)
中间件技术-处理错误
app.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') {
// res.status(401).send('invalid token...');
res.status(401).send({ status: 1, message: '身份认证失败!' });
}
});
前端统一携带token
统一设置Authorization
// $.ajaxSetup: 用来统一设置ajax的配置
$.ajaxSetup({
headers: {
Authorization: localStorage.getItem('token'),
}
})
// 随后发出的ajax就会携带token