如何在使用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
相关产品推荐
相关产品推荐

