Fastify 装饰器不充当 Fastify-REST-API 中的预处理程序

问题描述 投票:0回答:1

我对 Fastify 相当陌生,我正在使用它来构建 API。我在路由中使用身份验证装饰器时遇到了一些麻烦,抛出以下错误:“code”:“FST_ERR_HOOK_INVALID_HANDLER”,“name”:“FastifyError”,“statusCode”:500},“msg”:“ preHandler hook 应该是一个函数,而不是得到 [object Undefined]”。

我已经在以下位置设置了一个装饰器文件 @/decorators/authentication.ts

import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
import fjwt, { FastifyJWT } from "@fastify/jwt";
import fCookie from "@fastify/cookie";
import { env } from "@/config/constants";  // Ensure the correct path

export default async function authentication(app: FastifyInstance) {
  // Register JWT plugin
  app.register(fjwt, { secret: String(env.JWT_SECRET_KEY) });
  
  // Register cookies plugin
  app.register(fCookie, {
    secret: env.JWT_SECRET_KEY,
    hook: "preHandler",
  });

  // Decorate app with the authenticate function
  app.decorate(
    "authenticate",
    async (req: FastifyRequest, reply: FastifyReply) => {
      try {
        const token = req.cookies.access_token;
        if (!token) {
          return reply.status(401).send({ message: "Authentication required" });
        }
        // Verify the token and set the user in the request object
        const decoded = req.jwt.verify<FastifyJWT['user']>(token)
        req.user = decoded;
        
      } catch (err) {
        return reply.status(401).send({ message: "Invalid or expired token" });
      }
    }
  );
}

并使用它 @/modules/authentication/authentication.routes.ts

import { FastifyInstance } from "fastify";
import AuthenticationController from "./authentication.controller";
import UserService from "@/data-services/user-service";
import { $ref, userSchemas } from "./authentication.schema";

export default async function authRoutes(fastify: FastifyInstance) {
  // Decorate fastify with the user service
  fastify.decorate("userService", new UserService());

  // Register schemas
  userSchemas.forEach((schema) => fastify.addSchema(schema));

  const authController = new AuthenticationController(fastify.userService);

  // Login route
  fastify.post(
    "/login",
    {
      schema: {
        body: $ref("loginSchema"),
        response: {
          201: $ref("loginResponseSchema"),
        },
      },
    },
    authController.login.bind(authController)
  );

  // Register route
  fastify.post(
    "/registro",
    {
      schema: {
        body: $ref("registerUserSchema"),
        response: {
          201: $ref("registerUserResponseSchema"),
        },
      },
    },
    authController.register.bind(authController)
  );

  // Get current user route with preHandler for authentication
  fastify.get(
    "/me",
    {
      preHandler: [fastify.authenticate],
    },
    authController.getCurrentUser.bind(authController)
  );
}

我将我的 server.ts 文件设置为这样

import Fastify from "fastify";
import { env } from "./config/constants";
import "./types";
import authentication from "@/decorators/authentication";
import routes from "./config/routes";

const app = Fastify({
  logger: true,
});

const listeners = ["SIGINT", "SIGTERM"];
listeners.forEach((signal) => {
  process.on(signal, async () => {
    await app.close();
    process.exit(0);
  });
});

app.register(authentication);
app.register(routes);

app.listen(
  {
    port: env.PORT,
  },
  (err, address) => {
    if (err) {
      app.log.error(err);
      process.exit(1);
    }
    app.log.info(`server listening on ${address}, PORT: ${env.PORT}`);
  }
);

我正在 /me 路由上记录一个临时处理程序,但 fastify.authenticate 返回为未定义。谁能解释一下为什么会发生这种情况?

软件包版本

"@fastify/cookie": "^10.0.1",
 "@fastify/jwt": "^9.0.1",
  "fastify": "^5.0.0",
  "fastify-zod": "^1.4.0",

也已经检查过这些解决方案 相关堆栈溢出主题 Github相关问题 但没有找到答案

我试图使用我之前创建的装饰器方法对用户进行身份验证,但似乎不起作用,因为我的路线抱怨身份验证未定义。我已经在路由之前注册了身份验证装饰器,并添加了日志以确认装饰器在路由之前已正确注册。

node.js typescript authentication fastify fastify-jwt
1个回答
0
投票

问题是

fastify.authenticate
返回
undefined
这是因为
export default async function authentication(app: FastifyInstance)
插件不使用
fastify-plugin
模块
,因此当它注册时
app.register(authentication);
它会创建自己的上下文,不会影响
routes
模块。

要修复它,您需要包装该函数:

import fp from 'fastify-plugin'

export default fp(
  async function authentication(app: FastifyInstance) { ... }
)

有用的读物:

© www.soinside.com 2019 - 2024. All rights reserved.