这里使用的egg项目脚手架模板是simple版本,详细创建项目流程可在eggjs官网查阅
egg-jwt是适配egg的jwt鉴权插件
JWT请求流程
1、浏览器向服务器请求jwt口令
2、服务器创建jwt,并返回给浏览器
3、浏览器接受到服务器返回的jwt,并保存在本地(cookie、localStorage、sessionStorage均可)
4、浏览器之后向服务器发送的所有请求,默认都带上jwt,供服务器校验
5、服务器接收到请求,校验附带的jwt口令,校验通过则做后续工作,否则直接拒绝请求
安装egg-jwt
npm i egg-jwt -S
配置plugins.js config/plugins.js
jwt: {
enable: true,
package: 'egg-jwt',
},
配置 config.default.js config/config.default.js
config.jwt = {
secret: 'UzumakiHan' //自定义 token 的加密条件字符串
};
实践使用
app/controller/app.js
const { Controller } = require('egg');
class AppController extends Controller {
async login() {
const { ctx, app } = this;
const data = ctx.request.body;
const token = app.jwt.sign({
username: data.username,
permission:data.permission
}, app.config.jwt.secret, {
expiresIn: '30d' // '1d'、'24h'、60,其中数值单位为秒
});
console.log(token)
ctx.body = token;
}
async index() {
const { ctx, app,config } = this;
const token = ctx.headers.authorization ? ctx.headers.authorization.split(' ')[1] : '';
try {
const user = app.jwt.verify(token, config.jwt.secret);
ctx.success({
...user
});
} catch (error) {
ctx.error({
code:401,
message: error
})
}
}
}
module.exports = AppController;
注册路由
app/router.js
module.exports = app => {
const { router, controller,jwt } = app;
router.post('/app/login', controller.app.login);
router.post('/app/index',jwt, controller.app.index); //需要jwt 生成的token才能请求成功
};
发送请求生成token,这里就在postman中调用接口
生成了token,然后复制token,在/app/index请求中authorization带上token
数据返回成功,如果请求不带token会是怎样,以下是没有token的情况
数据返回不成功,因为/app/index这个接口是要jwt鉴权的
用户权限访问接口
如上图所示,这个用户permission为admin,例如我们要求一些接口是admin才能访问,其它身份的用户不能访问,可以这样去实现
编写对应的中间件,对jwt进行加工编写
app/middleware/jwt.js
module.exports = option=>{
return async function jwt(ctx,next){
const token = ctx.headers.authorization ? ctx.headers.authorization.split(' ')[1] : '';
try {
const verify = await ctx.app.jwt.verify(token, ctx.app.config.jwt.secret);
if (!option.includes(verify.permission)) {
ctx.status = 403;
ctx.error({
code: 403,
message: 'Permission is not authorized'
});
} else {
ctx.permission = verify.permission;
await next();
}
} catch (error) {
ctx.status = 401;
ctx.error({
code: 401,
message: error
});
}
}
}
app/router.js
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const { router, controller,middleware } = app;
const jwt = middleware.jwt;
router.post('/app/login', controller.app.login);
router.post('/app/index',jwt(['superadmin']), controller.app.index); //需要jwt 生成的token才能请求成功
};
现在/app/index只有permission是superadmin才能访问,之前生成token的permission是admin,所以现在请求/app/index就会不成功了
改为admin
router.post('/app/index',jwt(['admin']), controller.app.index); //需要jwt 生成的token才能请求成功
请求成功