需求
后端服务提供的接口应该是有时限和权限的,所以一般通过 token 进行用户权限的校验。
开发
安装
通过 egg-jwt 插件生成 token。
npm i --save egg-jwt
配置
在 plugin.js 中配置 egg-jwt 插件。
module.exports = {jwt: {enable: true,package: 'egg-jwt'},
};
在 config.default.js 中设置 jwt 相关内容,同时因为部分接口不需要校验 token,故在此处同时设置白名单。
// 添加jwt的配置
config.jwt = {secret: 'Jian1', // 加密密钥sign: {expiresIn: 60 * 60 * 24, // 过期时间24小时algorithm: 'HS256'}
}// 添加token白名单配置
config.tokenWhiteList = ['/login','/verifyCode',
]
生成
生成 token 的动作一般在调用 login 接口的时候进行,通过 login 接口将 token 传递给前端,一般保存在 localStore 中。
const token = app.jwt.sign(params, app.config.jwt.secret);
ctx.state = 200;
ctx.body = {code: 200,success: true,data: {token: token},msg: '欢迎回来,' + userInfo.name,show: true
}
校验
egg框架存在 中间件(middleware) 非常适合全局性质的拦截和校验。
创建 app/middleware/tokenAuth.js 文件。
module.exports = () => {return async function (ctx, next) {const requestUrl = ctx.request.url;if (ctx.app.config.tokenWhiteList.indexOf(requestUrl) > -1) {// 当前路由在白名单中await next();return;}const userToken = ctx.request.headers['authorization'].replace(/^Bearer\s+/, '');if (userToken) {try {ctx.app.jwt.verify(userToken, ctx.app.config.jwt.secret);await next();} catch (e) {ctx.status = 401;return ctx.body = {code: 401,msg: 'token错误'}return;}} else {ctx.status = 401;return ctx.body = {code: 401,msg: 'token不存在'}return;}}
}
总结
token 是比较重要的校验方式,但是需要注意的是常规来说:
前端传递 token 的时候需要加上 "Bearer "。
后端解析的时候需要去除 "Bearer "。
这里涉及到的其实是 W3C 的规范,请求头 Authorization 验证身份的时候遵守的格式是 Authorization: <type> <credentials>。
- type 是认证方式
- credentials 是认证信息
注意:这里前端不增加 "Bearer " 也是可以调通的,但是加上最好,原因是框架使然。详情可以参阅官方文档。