JWT 鉴权 基于 JSON WEB TOKEN 封装 中间件鉴权

优质
小牛编辑
132浏览
2023-12-01

导入 jsonwebtoken 包
文档:https://www.npmjs.com/package/jsonwebtoken
安装:npm install jsonwebtoken

egg 框架配置

config / config.default.js 中配置 jwt

/********** token 配置 **********/
config.jwt = {
secret: 'bcrypt',
expiresIn: 60*60*2 // 2小时过期
}

参数

secret : token 加密密钥
expiresIn:token 有效期

app / extend / context.js 扩展 ctx 属性

const jwt = require('jsonwebtoken');

module.exports = {
    get jwt() {
        return jwt
    },

    returnSucc(msg='成功', code=0, httpCode=200) {
        throw new global.myErrors(msg, code, httpCode)
    },

    returnError(msg='失败', code=1, httpCode=400) {
        throw new global.myErrors(msg, code, httpCode)
    },
}

配置中间件

app / config / config.default.js

/********** 中间件配置 **********/
config.middleware = ['errorHandler', 'auth'];
config.auth = {
 allowed: [
   '/api/v1/user/register',
   '/api/v1/user/login'
 ]
}

参数

allowed:不需要token验证的路由

书写中间件

app / middleware / auth.js

/**
 token 访问授权
 @param oprions { Array } 配置项:不需要鉴权的路由
 @param app { Object } 当前应用
 */
module.exports = (options, app) => {
  return async (ctx, next) => {
    // 1.排除不需要验证 token 的路由
    if (options.allowed.indexOf(ctx.request.url) > -1) return await next(options);

    //2. 获取 header 头token        
    const { authorization = '' } = ctx.header;
    if (!authorization) ctx.returnError('您没有权限访问该接口!', 0, 401);
    let token = authorization.replace('Bearer ', '')

    //3. 根据token解密,换取用户信息
    let user = {};
    try {
      user = ctx.jwt.verify(token, app.config.jwt.secret)
    } catch(err) {
      err.name === 'TokenExpiredError' ? ctx.returnError('token 已过期! 请重新获取令牌')
      : ctx.returnError('Token 令牌不合法!');
    }

    //4. 把 user 信息挂载到全局ctx上
    ctx.auth = {
      uid: user.uid,
      scope: user.scope
    }

    // 5. 继续执行
    await next(options);
  }
}

生成 token

app / extend / application.js

'use strict';

const jwt = require('jsonwebtoken');

module.exports = {
  /**
   * 生成 Token
   * @param { Object } params 参数
   */
  generateToken(params = {}) {
    return jwt.sign(params, this.config.jwt.secret, { expiresIn: this.config.jwt.expiresIn });
  },
};