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

如何在AWS Amplify托管的Next.js应用中为租户动态创建子域名?

为AWS Amplify上的Next.js多租户应用动态管理子域名方案

方案一:Wildcard子域名+应用内路由(快速实现)

这种方案适合大多数场景,无需动态创建独立子域名,通过通配符覆盖所有子域名,再在应用内识别租户并加载对应内容。

  • 1. 在Amplify配置Wildcard子域名
    进入Amplify应用的「域名管理」,点击「添加域名」,输入*.yourdomain.com,按照提示完成DNS验证(在Route 53添加对应的CNAME或A记录,Amplify会给出具体值)。等待Amplify完成SSL证书生成和部署,通常需要10-20分钟。

  • 2. Next.js中解析子域名并路由
    用Next.js的Middleware来拦截请求,提取子域名作为租户标识,再转发到对应页面:

    import { NextResponse } from 'next/server';
    import type { NextRequest } from 'next/server';
    
    export function middleware(request: NextRequest) {
      const hostname = request.headers.get('host') || '';
      // 匹配子域名,排除主域名、www等保留前缀
      const tenantMatch = hostname.match(/^([a-z0-9-]+)\.yourdomain\.com$/i);
      
      if (tenantMatch) {
        const tenantSlug = tenantMatch[1].toLowerCase();
        // 把租户标识通过请求头传递给页面,或者直接重写路径
        const modifiedHeaders = new Headers(request.headers);
        modifiedHeaders.set('x-tenant-slug', tenantSlug);
    
        // 重写请求到租户专属页面,比如/pages/tenant/[slug]
        return NextResponse.rewrite(
          new URL(`/tenant/${tenantSlug}`, request.url),
          { headers: modifiedHeaders }
        );
      }
    
      // 主域名请求直接放行
      return NextResponse.next();
    }
    
    // 指定中间件生效范围,排除静态资源和API路由
    export const config = {
      matcher: ['/', '/((?!api|_next/static|_next/image|favicon.ico).*)'],
    };
    

    在页面组件中,通过headers().get('x-tenant-slug')获取租户标识,再从数据库加载对应租户的数据。

  • 3. 租户注册时的校验
    注册页面需要检查租户名:

    • 只能包含小写字母、数字、连字符
    • 不能是保留词(如www、admin、api)
    • 在数据库中检查是否已被占用,确保唯一性

方案二:动态创建独立子域名(适合需单独配置的场景)

如果需要为每个租户单独配置SSL、分支映射等,可以结合Lambda+Route 53+Amplify API实现自动化创建。

  • 1. 编写Lambda函数处理子域名创建
    创建Lambda函数,负责租户注册后的子域名自动化流程:

    const AWS = require('aws-sdk');
    const amplify = new AWS.Amplify();
    const route53 = new AWS.Route53();
    
    exports.handler = async (event) => {
      const { tenantSlug, mainDomain } = event;
      const hostedZoneId = 'YOUR_ROUTE53_HOSTED_ZONE_ID';
      const amplifyAppId = 'YOUR_AMPLIFY_APP_ID';
      const amplifyCloudfrontDomain = 'YOUR_AMPLIFY_CLOUDFRONT_DOMAIN'; // 从Amplify域名管理中获取
    
      // 校验租户名合法性
      if (!/^[a-z0-9-]+$/.test(tenantSlug)) {
        return { statusCode: 400, body: JSON.stringify({ error: '租户名只能包含小写字母、数字和连字符' }) };
      }
    
      // 检查子域名是否已存在于Route 53
      const existingRecords = await route53.listResourceRecordSets({
        HostedZoneId: hostedZoneId,
        StartRecordName: `${tenantSlug}.${mainDomain}`,
        StartRecordType: 'CNAME'
      }).promise();
    
      if (existingRecords.ResourceRecordSets.length > 0) {
        return { statusCode: 409, body: JSON.stringify({ error: '该租户名已被占用' }) };
      }
    
      // 在Route 53添加CNAME记录
      await route53.changeResourceRecordSets({
        HostedZoneId: hostedZoneId,
        ChangeBatch: {
          Changes: [{
            Action: 'CREATE',
            ResourceRecordSet: {
              Name: `${tenantSlug}.${mainDomain}`,
              Type: 'CNAME',
              TTL: 300,
              ResourceRecords: [{ Value: amplifyCloudfrontDomain }]
            }
          }]
        }
      }).promise();
    
      // 在Amplify添加子域名映射
      await amplify.createDomain({
        appId: amplifyAppId,
        domainName: mainDomain,
        subDomainSettings: [{
          prefix: tenantSlug,
          branchName: 'main' // 映射到你的主分支
        }]
      }).promise();
    
      return { statusCode: 200, body: JSON.stringify({ message: '子域名创建成功,几分钟后即可使用' }) };
    };
    

    给Lambda配置权限:允许访问Route 53的记录读写、Amplify的域名管理操作。

  • 2. 集成到租户注册流程
    在Next.js的注册页面,通过API Gateway调用该Lambda函数,传入租户名和主域名。用户提交注册后,等待Lambda完成操作,Amplify会自动为子域名申请ACM证书,通常需要5-10分钟,之后租户即可使用<tenant>.yourdomain.com访问。

  • 3. 注销清理
    当租户注销时,需要调用另一个Lambda函数,删除Route 53中的对应记录和Amplify中的子域名配置。


注意事项

  • SSL证书:两种方案Amplify都会自动通过ACM申请免费SSL证书,无需手动处理
  • 性能:Wildcard方案几乎无延迟,适合快速上线;动态方案需要等待证书生成,适合有特殊配置需求的场景
  • 唯一性校验:必须在注册环节严格检查租户名,避免冲突

内容的提问来源于stack exchange,提问作者Syed Haider Ali Zaidi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 19:55:19