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

Posted 凯小默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了eggjs 怎么使用 egg-jwt 实现登录验证中间件?相关的知识,希望对你有一定的参考价值。

为什么要写验证中间件?

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

实现登录验证中间件

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

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

1、新建中间件

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

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、使用中间件

我们可以参考 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不存在"

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


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

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

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

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

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

但是控制台会报另外一个错误了:error JsonWebTokenError: invalid token,说这个是一个 无效的token,具体的可以去看一下逻辑。

4.3 token 正常的情形

输入正常的 token

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

以上是关于eggjs 怎么使用 egg-jwt 实现登录验证中间件?的主要内容,如果未能解决你的问题,请参考以下文章

eggjs 怎么使用 egg-jwt 实现 token 解析?

eggjs 怎么实现获取用户信息接口?

设计数据库表:用于 eggjs 实现记账本

eggjs 怎么实现新增账单接口?

eggjs 怎么实现用户注册功能?

eggjs 怎么实现获取账单类型字典接口?