eggjs 怎么使用 egg-jwt 实现登录验证中间件?

本文涉及的产品
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: eggjs 怎么使用 egg-jwt 实现登录验证中间件?

为什么要写验证中间件?

原因很简单,就是将重复的逻辑抽离出来,用于校验需要校验的接口。还可以避免逻辑改动导致所有接口逻辑调整,提高代码的可维护性。


实现登录验证中间件


Egg 的中间件形式和 Koa 的中间件形式是一样的,都是基于洋葱圈模型。每次我们编写一个中间件,就相当于在洋葱外面包了一层。


中间件的写法请参考:中间件(Middleware)

3ced3c4859be4de3a67f7cdc2554eb7b.png


1、新建中间件

在 app 文件夹里新建 middleware 文件夹,里面新建一个 verifyToken.js 校验文件。


98efc96fdf8c40068cb157bc1f9d3356.png



2、实现中间件

2.1 首先需要返回一个异步函数出去

'use strict';
module.exports = (secret) => {
  return async function verifyToken(ctx, next) {
  }
};


2.2 获取 token

// 若是没有 token,返回的是 null 字符串
const token = ctx.request.header.authorization;


2.3 判断 token 有没有

if(token != 'null' && token) {
  // 有token 需要校验
} else {
  // token 不存在
  ctx.status = 200;
  ctx.body = {
    status: 401,
    desc: 'token不存在'
  };
}


2.4 有 token 需要校验

// 有 token 需要校验
try {
  let decode = ctx.app.jwt.verify(token, secret);
  console.log('token 需要校验', decode);
  await next();
} catch (error) {
  console.log('error', error)
  ctx.status = 200;
  ctx.body = {
    status: 401,
    desc: 'token已过期,请重新登录'
  }
}


整个代码如下:

'use strict';
module.exports = (secret) => {
  return async function verifyToken(ctx, next) {
    // 若是没有 token,返回的是 null 字符串
    const token = ctx.request.header.authorization;
    if(token != 'null' && token) {
      // 有 token 需要校验
      try {
        let decode = ctx.app.jwt.verify(token, secret);
        console.log('token 需要校验', decode);
        await next();
      } catch (error) {
        console.log('error', error)
        ctx.status = 200;
        ctx.body = {
          status: 401,
          desc: 'token已过期,请重新登录'
        }
      }
    } else {
      // token 不存在
      ctx.status = 200;
      ctx.body = {
        status: 401,
        desc: 'token不存在'
      };
    }
  }
};



3、使用中间件

92b1ae395b2b484692e3c958de7b90ba.png


我们可以参考 egg 的官网例子,在 router.js 里添加代码如下:

'use strict';
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller, middleware } = app;
  // 传入加密字符串
  const verify_token = middleware.verifyToken(app.config.jwt.secret);
  // 测试 token 解析
  router.get('/api/user/token', verify_token, controller.user.getTokenInfo);
};



4、测试中间件


4.1 先测试没有 token 的情形

{
    "status": 401,
    "desc": "token不存在"
}


ede38903666f44dbb8106b696a70c9ec.png


4.2 测试有 token 但是过期的情形

{
    "status": 401,
    "desc": "token已过期,请重新登录"
}

2d3c1d9ff1f3432682c18a3428bc91a8.png


报这个的原因是因为:jwt 报错 error JsonWebTokenError: jwt malformed

64fe4bea2e1242639c3b54709f303f0b.png


这个可以参考这个文件https://github.com/auth0/node-jsonwebtoken/blob/master/verify.js,就是说 jwt 字符串不是 xxx.xxx.xxx 的格式类型;

   egg-jwt 依赖于 koa-jwt2 , koa-jwt2 依赖于 jsonwebtoken


21c8fe14bceb4f8e888301d86b2e498f.png



我们改一下,改成 xxx.xxx.xxx 类型的


2d55db9eed4c4a2a9cbb7d08ba50a1b2.png



误了:error JsonWebTokenError: invalid token,说这个是一个 无效的token,具体的可以去看一下逻辑。

d0decd5def9a456c9ecee57a2efa5d3e.png



4.3 token 正常的情形

输入正常的 token


d6a137e1604b4cdaa96135efde607201.png


控制台打出了 token 需要校验的逻辑,说明正常请求成功了。


37cee9ecfda34a878378507877ab7f0d.png












目录
相关文章
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
685 0
|
5月前
|
存储 中间件 API
权限验证中间件中模拟权限检查函数的具体逻辑
权限验证中间件中模拟权限检查函数的具体逻辑
198 67
|
12月前
|
JSON 安全 算法
|
安全 Java 应用服务中间件
Shiro + JWT 进行登录验证
Shiro + JWT 进行登录验证
108 2
|
存储 中间件 API
ThinkPHP 集成 jwt 技术 token 验证
本文介绍了在ThinkPHP框架中集成JWT技术进行token验证的流程,包括安装JWT扩展、创建Token服务类、编写中间件进行Token校验、配置路由中间件以及测试Token验证的步骤和代码示例。
ThinkPHP 集成 jwt 技术 token 验证
|
12月前
|
JavaScript
Node.js单点登录SSO详解:Session、JWT、CORS让登录更简单(二)
Node.js单点登录SSO详解:Session、JWT、CORS让登录更简单(一)
379 0
|
12月前
|
存储 JSON JavaScript
Node.js单点登录SSO详解:Session、JWT、CORS让登录更简单(一)
Node.js单点登录SSO详解:Session、JWT、CORS让登录更简单(一)
398 0
【Azure APIM】在APIM中实现JWT验证不通过时跳转到Azure登录页面
【Azure APIM】在APIM中实现JWT验证不通过时跳转到Azure登录页面
【Azure Developer】记录一段验证AAD JWT Token时需要设置代理获取openid-configuration内容
【Azure Developer】记录一段验证AAD JWT Token时需要设置代理获取openid-configuration内容
127 0
|
JSON Java API
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
【Azure Developer】如何验证 Azure AD的JWT Token (JSON Web 令牌)?
333 0