jwt不是egg内置的,所以我们先进行全局安装:
npm install egg-jwt -S
在config文件夹里面的plugin.js引入:
module.exports = {
// 其他引入
...
jwt: {
enable: true,
package: "egg-jwt"
}
};
在config文件夹里面的config.default.js里面配置:
module.exports = appInfo => {
//其他配置
...
// 这个是配置跨域的,取消csrf
config.security = {
csrf: {
enable: false,
}
};
// 全局配置jwt
config.jwt = {
secret: "123456" //这个是加密秘钥,自行添加
};
return {
...config // es6语法,解构
};
};
在你需要返回数据的controller或者service里面添加以下代码,在登录的时候返回给客户端:
const { ctx } = this;
const token = await ctx.app.jwt.sign({ openid: resData.openid }, ctx.app.config.jwt.secret, { expiresIn: "24h" });
ctx.status = 200;
ctx.body = {
msg: '登录成功',
token
}
这里可以看见openid,这部分代码是从小程序的项目里面截取出来的 ,本人现在的状态就是一边开发项目一边用文章的形式记录知识点,希望大家能喜欢。改天再持续讲讲用egg.js实现小程序的登录功能。
在controller里面验证token:
const { ctx } = this;
const token = ctx.request.header.authorization;
//使用插件验证需要加Bearer 自定义中间件验证不需要加
try {
//在操作数据之前先验证token
ctx.app.jwt.verify(token, ctx.app.jwt.secret);
const user = await ctx.model.User.findAll()
ctx.body = {
code:0,
data:user
}
} catch (error) {
//如果没能验证成功
ctx.body = "token验证失败"
}
但是在controller里面需要一个个去验证,不太现实,所以我们通过中间件的方法来验证token,最后把它挂载到路由上。
在app
文件夹里面新增middleware
文件夹,创建jwtVerify.js
文件:
'use strict';
// 定制白名单
const whiteList = [ '/user/login', '/user/register' ];
module.exports = (options) => {
return async function(ctx,next){
if(!whiteList.some(item=>item==ctx.request.url)){//判断接口路径是否在白名单
let token = ctx.request.header.authorization//拿到token
if(token){//如果token存在
let decoded = ctx.app.jwt.verify(token, ctx.app.config.jwt.secret)//解密token
if(decoded&&decoded.openid){
ctx.body={
code:0,
openid :decoded.openid
}
}else{
ctx.openid=decoded.openid//把openid存在ctx上,方便后续操作。
await next()
}
}else{
ctx.body={
code:0,
msg:'没有token'
}
}
}else{
await next()
}
}
}
然后在路由中使用这个中间件jwtVerify
:
module.exports = app => {
const { router, controller, middleware } = app;
router.get('/detail', middleware.jwtVerify(app.config.jwt), controller.home.detail);
};
接着测试一下没有带token的结果:
这里最后给大家留个问题吧,遇见invalid token 的时候,该怎么处理?大家评论区自由发挥~