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

如何在使用Fastify适配器的NestJS中实现子域名路由?

问题解决:NestJS + Fastify 子域名路由约束不生效

问题场景

根据NestJS相关说明,Fastify不支持嵌套路由,但可通过RouteConfig结合Fastify的host constraints实现子域名路由限定。尝试以下代码后发现配置不生效:顶级域名与子域名均能匹配到同一接口。

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { RouteConfig } from '@nestjs/platform-fastify';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @RouteConfig({
    constraints: { host: 'admin.example.com' },
  })
  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

原因解析

NestJS的RouteConfig装饰器在Fastify适配器中,默认不会自动处理host约束的精确匹配逻辑。当未给其他路由设置明确host约束时,Fastify会将无约束的路由视为匹配所有域名,导致顶级域名也能访问子域名限定的接口。

解决方案

要实现严格的子域名路由隔离,需给所有路由(包括顶级域名路由)配置明确的host约束,或通过Fastify实例直接添加路由级别的host验证逻辑。

方案1:为所有路由添加明确Host约束

给顶级域名的路由也配置RouteConfig,指定对应host,让Fastify精确匹配不同域名的路由:

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { RouteConfig } from '@nestjs/platform-fastify';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  // 子域名admin.example.com专属路由
  @RouteConfig({
    constraints: { host: 'admin.example.com' },
  })
  @Get('admin')
  getAdminHello(): string {
    return this.appService.getAdminHello();
  }

  // 顶级域名example.com专属路由
  @RouteConfig({
    constraints: { host: 'example.com' },
  })
  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

方案2:通过Fastify实例配置全局Host验证钩子

在NestJS启动时,直接给Fastify实例添加前置钩子,手动校验请求的host:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  // 全局钩子:验证请求host是否合法
  app.getHttpAdapter().getInstance().addHook('onRequest', (request, reply, done) => {
    const allowedHosts = ['admin.example.com', 'example.com'];
    if (!allowedHosts.includes(request.hostname)) {
      reply.code(404).send('Not Found');
      return;
    }
    done();
  });

  await app.listen(3000);
}
bootstrap();

关键注意事项

  • Fastify的host约束支持正则表达式,如需匹配通配符(如*.example.com),可写为:constraints: { host: /^.*\.example\.com$/ }
  • 本地测试时,需在hosts文件中配置域名映射(如127.0.0.1 admin.example.com example.com)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 08:37:37