在 Laravel 11 中使用 stancl/tenancy 实现租户自定义域名,需禁用默认子域名识别,启用 DomainStrategy;在 Tenant 模型添加 custom_domain 字段并验证;通过 Route::domain('{domain}')->where('.*') 配合中间件从 Host 头匹配租户;编写 InitializeTenancyByDomain 中间件查库并调用 $tenant->makeCurrent();最后配置 Nginx 泛 server_name 和 DNS 解析。

在 Laravel 11 中使用 stancl/tenancy 实现租户自定义域名(如 shop.mybrand.com 或 client-a.com),核心在于绕过默认的子域名({tenant}.example.com)约束,改用「任意域名」作为租户标识,并确保路由识别、数据库切换和中间件执行全部适配该模式。
1. 启用自定义域名支持(非子域名)
stancl/tenancy 默认基于子域名识别租户,但支持通过 自定义识别器(Identifier) 支持任意域名。你需要禁用默认的 SubdomainTenant 识别器,启用 DomainTenant 或自定义逻辑:
- 在
config/tenancy.php中修改识别方式:'identification' => [ 'strategies' => [ \Stancl\Tenancy\Identification\Strategies\DomainStrategy::class, ], ], - 确保
central_domains列表只包含管理后台域名(如admin.yoursaas.com),不包含租户域名;租户域名需单独存入数据库(见下一步)
2. 在租户模型中存储并验证 custom_domain
每个租户记录需保存一个或多个合法域名。推荐在 Tenant 模型中增加字段:
- 添加迁移:运行
php artisan make:migration add_custom_domain_to_tenants_table,在up()中添加:$table->string('custom_domain')->nullable()->unique(); // 或用 JSON 字段存多个域名 - 在
Tenant模型中添加访问器或作用域,例如:public function getCustomDomainAttribute() { return $this->attributes['custom_domain'] ?? null; } - 确保创建租户时可设置该字段(如通过 Seeder、API 或管理后台)
3. 路由层匹配任意域名并绑定租户
Laravel 不支持通配符域名(如 *.com)直接路由,但可通过 Route::domain('{domain}') → where('domain', '.*') 配合中间件实现动态匹配:
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 在
app/Providers/RouteServiceProvider.php的mapWebRoutes()方法开头添加:Route::domain('{domain}') ->where('domain', '.*') ->middleware(['web', 'initialize-tenancy-by-domain']) ->group(base_path('routes/tenant.php')); - 注意:必须放在
require base_path('routes/web.php')之前,否则会被根域名路由拦截 - 不要在
routes/web.php中写Route::domain()—— 它只在RouteServiceProvider中注册才生效
4. 编写初始化租户中间件(关键步骤)
新建中间件 app/Http/Middleware/InitializeTenancyByDomain.php,逻辑如下:
- 从请求 Host 头获取完整域名:
$host = $request->getHost(); - 查库匹配租户:
$tenant = Tenant::where('custom_domain', $host)->first(); - 验证有效性(状态 active、未过期等),失败则返回 404 或重定向到首页
- 调用
$tenant->makeCurrent();激活租户上下文(stancl/tenancy 自动处理连接、缓存、队列等隔离) - 务必把该中间件加到
$middlewareGroups['web']最前面(app/Http/Kernel.php),早于 Session、Auth 等中间件
5. Web 服务器与 DNS 配置
后端逻辑跑通后,还需基础设施支持:
-
Nginx:server_name 必须覆盖所有租户域名,推荐用泛配置:
server_name ~^(?<domain>.+)$; # 或明确列出:server_name client-a.com shop.mybrand.com;</domain>
- DNS:每个租户域名 A 记录指向你的服务器 IP(无需泛解析,但需实际配置)
-
本地开发:在
/etc/hosts添加多行,例如:127.0.0.1 client-a.com 127.0.0.1 shop.mybrand.com
-
HTTPS:生产环境建议用 wildcard SSL(如
*.yoursaas.com)或 Let’s Encrypt 自动签发(配合 acme.sh 或 Certbot)










