You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Fastify中为路由设置Scope授权并实现权限校验

实现带参数的Fastify authenticate钩子用于权限校验

1. 修改authenticate装饰器为高阶函数

将原有的authenticate直接处理函数改为高阶函数,使其能接收权限参数并返回符合Fastify钩子要求的请求处理函数,以此实现带参数的调用方式。

修改后的JWT注册代码:

import fjwt from "@fastify/jwt";
import buildGetJwks from "get-jwks";

export default function register(fastify) {
  const getJwks = buildGetJwks({
    providerDiscovery: false,
    jwksPath: ".well-known/openid-configuration/jwks",
  });

  fastify.register(fjwt, {
    decode: { complete: true },
    secret: (request, token) => {
      const {
        header: { kid, alg },
        payload: { iss },
      } = token;
      return getJwks.getPublicKey({ kid, domain: iss, alg });
    },
    formatUser: function (user) {
      return {
        scope: user.scope,
      };
    },
  });

  // 改为高阶函数:接收权限参数,返回钩子处理函数
  fastify.decorate("authenticate", function (requiredScope) {
    return async function (request, reply) {
      try {
        // 先验证JWT有效性,验证通过后request.user会被填充
        await request.jwtVerify();
        
        // 校验权限(若传入了requiredScope)
        if (requiredScope) {
          const userScope = request.user.scope;
          // 兼容scope为字符串(如"read write")或数组的情况
          const userScopes = typeof userScope === 'string' ? userScope.split(' ') : userScope;
          
          if (!userScopes.includes(requiredScope)) {
            reply.code(403).send({ error: 'Forbidden', message: 'Insufficient permissions' });
            return;
          }
        }
      } catch (err) {
        reply.send(err);
      }
    };
  });
}

2. 在路由中使用带参数的authenticate

现在可以直接在onRequest钩子中传入带权限参数的调用,生成对应权限校验的钩子函数:

fastify.post(
  "/",
  {
    onRequest: [fastify.authenticate('create:news')], // 传入需要的权限scope
  },
  async (req, reply) => {
    sem.take(async () => {
      let _news = createNews(req.body);
      if (_news) await generate(_news);
      sem.leave();
    });
    return { status: 'accepted' };
  }
);

关键逻辑说明

  • 高阶函数的作用:让authenticate能够接收权限参数,并返回一个绑定了该参数的请求处理函数,完全符合Fastify对onRequest钩子的签名要求。
  • 权限校验流程:先完成JWT身份验证,再从request.user中获取用户权限列表,校验是否包含目标权限;权限不足时返回403 Forbidden错误,JWT验证失败则直接返回原错误。

内容的提问来源于stack exchange,提问作者mohazh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 05:07:25