egg-jwt的使用

安裝

npm install egg-jwt --save

配置

// config/config.default.js
config.jwt = {
    secret: 'zidingyi', // 自定義 token 的加密條件字元串
  };
// config/plugin.js
  jwt: {
    enable: true,
    package: 'egg-jwt',
  },

使用

  • 生成token
 // login.js
 const token = ctx.app.jwt.sign({
      ...ctx.request.body,
    }, this.app.config.jwt.secret, {
      expiresIn: '600m', // 時間根據自己定,具體可參考jsonwebtoken插件官方說明
    });
  • 驗證token

驗證token通常會寫一個中間件,在需要驗證的路由里引用中間件即可

'use strict';

module.exports = options => {
  return async function jwt(ctx, next) {
    // 拿到傳會數據的header 中的token值
    const token = ctx.request.header.authorization;
    const method = ctx.method.toLowerCase();
    // 當前請求時get請求,執行接下來的中間件
    if (method === 'get') {
      await next();
      // 當前token值不存在的時候
    } else if (!token) {
      if (ctx.path === '/api/v1/register' || ctx.path === '/api/v1/login/account') {
        await next();
      } else {
        ctx.throw(401, '未登錄, 請先登錄');
        ctx.body = {
          code: 50008,
        };
      }
    } else { // 當前token值存在
      let decode;

      // 解碼token
      decode = await ctx.app.jwt.verify(token, options.secret, (err, decoded) => {
        if (err) {
          if (err.name === 'TokenExpiredError') { // token過期
            return 'TokenExpiredError';
          } else if (err.name === 'JsonWebTokenError') { // 無效的token
            return 'JsonWebTokenError';
          }
        } else {
          return decoded;
        }
      });

      if (decode === 'TokenExpiredError') {
        ctx.body = {
          code: 401,
          msg: '登錄過期,請重新登錄',
        };
        return;
      }

      if (decode === 'JsonWebTokenError') {
        ctx.body = {
          code: 50012,
          msg: 'token無效,請重新登錄',
        };
        return;
      }
      await next();
    }
  };
};

  • 使用中間件鑒權
// router.js
const jwt = app.middleware.jwt(app.config.jwt);

router.post('/getHousePropertyFee', jwt, controller.getHousePropertyFee.index);

前端處理

  • 獲取token

login登錄成功後,後台會把token發送給前端,前端可以將token快取至cookie中。

  • 發送token

封裝axios,每次請求去cookie中拿token,並根據後端返回的狀態碼給予用戶提示,比如:token已過期等。。。

// 封裝axios請求
service.interceptors.request.use(
  config => {

    if (store.getters.token) {
      config.headers['authorization'] = getToken()
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// axios 攔截錯誤碼
if (res.code === 50016) {
      MessageBox.confirm(res.msg, '提示', {
        showClose: false,
        showCancelButton: false,
        closeOnClickModal: false,
        closeOnPressEscape: false,
        confirmButtonText: '確定',
        type: 'warning'
      })
    }

image

Tags: