Laravel 8 实现客户专属多子域名在共享主机无法生效问题求助
问题修复方案
一、共享主机侧配置调整
本地运行正常但共享主机失效,90%的情况是主机侧配置不匹配导致的,按以下步骤排查:
- 泛域名解析与绑定:首先确认你已在域名服务商处添加了泛解析记录,记录类型选A/AAAA,主机记录填
*,指向共享主机的公网IP;同时联系共享主机服务商确认已开通泛子域名支持,且*.你的主域名.com已绑定到项目的public入口目录,和主域名指向同一个站点根目录。 - 服务端HOST参数透传:确认共享主机的Web服务(Apache/Nginx)配置未篡改
HTTP_HOST参数,部分共享主机搭配CDN使用时会把HOSTheader改为后端节点域名,可在代码中临时打印$request->getHost()的值确认是否和实际访问的子域名一致。 - 会话目录权限:确保项目
storage/framework/sessions目录权限为755,属主和Web运行用户一致,避免会话无法写入导致校验逻辑失效。
二、中间件代码逻辑修复
原代码存在多处逻辑缺陷和兼容性问题,修复后代码如下:
class CheckTenantUser { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { // 提前配置主域名到.env文件:MAIN_DOMAIN=site.com $mainDomain = config('app.main_domain', env('MAIN_DOMAIN', 'site.com')); $host = $request->getHost(); // 本地调试兼容 if (str_contains($host, 'localhost') || str_contains($host, '127.0.0.1')) { $subdomain = 'default'; // 本地测试可指定默认租户slug } else { // 兼容多级主域名,例如site.com.cn也能正确提取子域名 $domainParts = explode('.', $host); $mainDomainParts = explode('.', $mainDomain); $subdomainParts = array_slice($domainParts, 0, count($domainParts) - count($mainDomainParts)); $subdomain = implode('.', $subdomainParts); } $hasAccess = $request->session()->get('has_access'); $currentTenant = $request->session()->get('currentClient'); // 已有权限且租户匹配直接放行 if ($hasAccess && $currentTenant && $currentTenant->slug === $subdomain) { return $next($request); } // 清除过期会话数据 $request->session()->forget(['has_access', 'currentClient']); // 查询租户 $tenant = Client::where('slug', $subdomain)->where('status', 1)->first(); if (!$tenant) { return redirect('/login')->with('no_access', true); } $request->session()->put('currentClient', $tenant); // 未登录用户直接放行到登录页 if (!$request->user()) { return $next($request); } // 校验登录用户是否属于当前租户 if ($request->user()->tenant->id !== $tenant->id) { return redirect('/login')->with('no_access', true); } $request->session()->put('has_access', true); return $next($request); } }
额外配置补充
修改config/session.php中的domain配置,实现所有子域名共享会话:
'domain' => '.' . env('MAIN_DOMAIN', 'site.com'),
同时在.env文件中添加主域名配置:
MAIN_DOMAIN=site.com
内容的提问来源于stack exchange,提问作者Mahmoud Sehsah
相关产品推荐
相关产品推荐

