koa-router如何给每个api添加一个基于jwt的token验证的方法?

发布于 2022-09-06 01:52:02 字数 832 浏览 28 评论 0

// valid.js
module.exports = function(req) {
    const token = req.headers['x-access-token'];
    return jwt.verify(token, PRIMARY_KEY, function (err, decoded) {
        if (err) {
            return {
                success: false,
                data: {
                    code: -101,
                    message: 'Failed to authenticate token.'
                }
            }
        }
        return {
            success: true,
        }
    })
}
// api.js
const tokenValid = require('../tokenValid');

router.post('/api/a', async(ctx, next) => {
    const valid = tokenValid(ctx.request);
    if (!valid.success) {
      ctx.rest(valid.data);
      return;
    }
    // todo
})

如果我有很多个接口,岂不是每个api中都要写一段重复代码。但是如何对async进行封装,使得每个接口不需要在考虑token,除了登陆和注册。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寄人书 2022-09-13 01:52:02

你需要将你的jwt验证逻辑包装Promise,返回true,false
中间件,检测登录

const checkLogin = async(ctx,next)=> {
    if(['/login'].indexOf(ctx.url)!==-1){
    await next();
    return;
    }
    const isLogin = await valid();
    if(!isLogin) {
        ctx.throw(401);
    }
    await next();
}

路由

cosnt router = new Router();
router.use(checkLogin);
// 接下来都是通过认证的
年少掌心 2022-09-13 01:52:02

router.use() 方法需要指定指定一个路由,且这个路由只能进行完全匹配,eg:
router.use('/api/auth', tokenValid)只能对api/auth这个api做token验证。使用了正则做模糊匹配,好像也不行。

最后我在api.js 入口文件中,使用了如下代码

// token valid
app.use(async function (ctx, next) {
    // 必须保证是api,因为路由和资源请求好像也会经过这里
  if (ctx.url.indexOf('/api') > -1 && ctx.url.indexOf('/api/auth/') === -1) {
    const token = ctx.request.header['x-access-token']  // X-Access-Token 会被转换成小写
    jwt.verify(token, TOKEN_PRIMARY_KEY, function (err, decoded) {
      console.log('err: ', err);
      if (err) {
          ctx.response.status = 401;
          ctx.response.body = {
            code: -100,
            message: 'invalid token',
          };
      }
    })
  }
   // 这里有一个问题,即使验证没通过,也会接着执行
  await next();
})

这里使用app.use可以获取到每个路由,每个请求。但是呢,这里的ctx.requst只能获取到ctx.request.headers而获取不到ctx.request.body。这点没想明白,可能和安全有关系吧。

之后在前端代码对axios封装的时候,加上

headers: {
  'X-Access-Token': window.localStorage.getItem('token'),
  'X-Requested-With': 'XMLHttpRequest'
},

token是登录接口返回的,存在localstorage里面

∝单色的世界 2022-09-13 01:52:02

router.use的path参数是可选的

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文