在做egg-jwt鉴权之前,需先设置跨域请求
// config.default.js
// 跨域设置
config.security = {
csrf: {
enable: false
},
domainWhiteList: [ '*' ]
};
config.cors = {
origin: '*',
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS'
};
安装egg-jwt
npm i egg-jwt --save
配置plugin.js
// plugin.js
// 鉴权
jwt: {
enable: true,
package: "egg-jwt"
}
在config.default.js配置中间件
// config.default.js
config.middleware = [ 'errorHandler','tokenHandler' ];
// 中间件执行匹配开启
config.tokenHandler = {
match(ctx) { // 只匹配指定路由,反之如果只忽略指定路由,可以用ignore
//匹配不需要验证token的路由
const url = ctx.request.url;
if (url.startsWith('/login')) {
// ctx.logger.info('config.tokenHandler:','关闭token验证')
return false;
} else {
// ctx.logger.info('config.tokenHandler:','开启token验证')
return true; // 开启中间件,开启token验证
}
}
};
无论是应用层加载的中间件还是框架自带中间件,都支持几个通用的配置项:
enable:控制中间件是否开启。
match:设置只有符合某些规则的请求才会经过这个中间件。
ignore:设置符合某些规则的请求不经过这个中间件。
三种配置项不要同时使用否则不生效!
egg中间件使用规则
tokenHandler jwt解码中间件
'use strict';
module.exports = (options) => {
return async function(ctx, next) {
const token = ctx.request.header.authorization;
let decode = '';
if (token) {
try {
// 解码token
decode = ctx.app.jwt.verify(token, options.secret);//验证token
console.log('decode======>', decode);
// 获取用户信息
ctx.decode = decode;
} catch (error) {
ctx.status = 401;
ctx.body = {
message: error.message,
};
return;
}
//切记先解析token并存储数据后再执行回调,否则解析数据获取不到x
await next();
} else {
ctx.status = 401;
ctx.body = {
message: '没有token',
};
return;
}
};
};
helper.js生成token
// 有效时间为30分钟
exports.getToken = function(options) {
return this.app.jwt.sign(options, this.app.config.jwt.secret, { expiresIn: '1800s' });
};
在server层使用helper生成的token
class LoginService extends Service {
async login() {
const { ctx } = this;
const { username, password } = ctx.request.body;
const [ User ] = await ctx.model.User.findAll({
where: {
username,
password
}
});
if (User) {
// 生成token
const token = ctx.helper.getToken({ username, password });
console.log(token)
return ctx.helper.success({ ctx, res: { login: true, token, id: User.id }, msg: '登录成功!' });
} else {
return ctx.helper.success({ ctx, res: { login: false }, msg: '用户名密码错误!' });
}
}
}
在server层使用 使用token解析后的数据
async getUserInfo() {
const { ctx, app } = this;
// 获取token解析后的用户信息
const { username, password } = ctx.decode;
const [ User ] = await ctx.model.User.findAll({
where: {
username,
password
}
});
return ctx.helper.success({ ctx, res:User, msg: '请求成功!' });
}
本代码为个人项目使用,有问题请查证版本