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

Laravel多租户场景下如何为单租户配置多个二级域名?

这个需求完全可以实现,你当前的配置存在两个核心问题,导致域名匹配失败、租户无法解析:

  • 域名路由规则层级错误:你当前配置的admin.localhost、employee.localhost仅能匹配二级域名段为admin/employee的请求,无法匹配你需要的{租户标识}.{角色}.localhost三级域名结构,请求匹配不到对应路由自然会fallback到无域名约束的公共路由。
  • 多租户默认解析逻辑不兼容三级域名:Spatie多租户默认的域名租户识别逻辑,是取域名最左段子域作为租户标识匹配,但默认逻辑没有处理多段子域的场景,直接拿全量子域匹配自然找不到对应租户。
具体修复步骤

1. 调整路由域名匹配规则

修改RouteServiceProvider中的路由定义,按照三级域名结构配置匹配规则,注意公共无租户路由要放在最顶部,避免被带参数的域名路由优先匹配:

// 公共无租户路由(安全、登录等页面)放最前面
Route::middleware('web')
    ->group(base_path('routes/security.php'));

// 租户默认前台路由,匹配 {tenantSlug}.localhost 结构
Route::domain('{tenantSlug}.' . config('app.base_domain'))
    ->middleware('web')
    ->group(base_path('routes/tenant.php'));

// 租户后台路由,匹配 {tenantSlug}.admin.localhost 结构
Route::domain('{tenantSlug}.admin.' . config('app.base_domain'))
    ->middleware('web')
    ->name('admin.')
    ->group(base_path('routes/admin.php'));

// 租户员工端路由,匹配 {tenantSlug}.employee.localhost 结构
Route::domain('{tenantSlug}.employee.' . config('app.base_domain'))
    ->middleware('web')
    ->name('employee.')
    ->group(base_path('routes/employee.php'));

提示:路由中定义的{tenantSlug}参数不需要在控制器方法中注入,后续租户解析逻辑会直接从请求主机名读取,不会影响原有路由的方法签名。

2. 自定义租户查找逻辑,适配三级域名结构

默认的租户查找类仅支持单段子域的租户识别,需要新建自定义租户查找类适配多子域场景:
新建文件app/TenantFinder/SubdomainTenantFinder.php,写入以下代码:

<?php

namespace App\TenantFinder;

use Illuminate\Http\Request;
use Spatie\Multitenancy\Models\Tenant;
use Spatie\Multitenancy\TenantFinder\TenantFinder;

class SubdomainTenantFinder extends TenantFinder
{
    public function findForRequest(Request $request): ?Tenant
    {
        // 拆分主机名段
        $hostSegments = explode('.', $request->getHost());
        // 无论域名后缀是1段(localhost)还是多段(example.com),第一个段永远是租户slug
        $tenantSlug = $hostSegments[0] ?? null;

        if (!$tenantSlug) {
            return null;
        }

        // 按照你自己租户表存租户标识的字段调整,默认如果用id匹配就改对应查询逻辑
        return Tenant::where('slug', $tenantSlug)->first();
    }
}

修改多租户配置文件config/multitenancy.php,将默认的租户查找类替换为自定义类:

'tenant_finder' => \App\TenantFinder\SubdomainTenantFinder::class,

3. 本地环境域名解析配置

本地开发需要确保所有三级域名能指向你的Laravel项目,两种方案选一个即可:

  • 方案1:在本地hosts文件中手动添加所有需要用到的域名映射到127.0.0.1
  • 方案2:配置dnsmasq做泛域名解析,将*.localhost统一指向127.0.0.1,后续新增租户不需要重复修改hosts

4. 清除缓存验证

执行路由清除命令php artisan route:clear,再访问对应域名验证:

  • 访问company-a.localhost正常加载租户前台页面
  • 访问company-a.admin.localhost加载admin.php路由定义的后台内容,可通过currentTenant()正常获取company-a租户信息
  • 访问company-a.employee.localhost加载employee.php路由定义的员工端内容

常见排查点:如果还是匹配异常,先执行php artisan route:list查看所有路由的domain字段是否和预期一致,确认路由规则生效;再检查hosts配置是否正确,确保请求能到达Laravel项目。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:42:04