Laravel多域名同应用Session认证:动态设置SESSION_DOMAIN及Octane影响咨询
嘿,针对你遇到的多域名SPA认证问题,尤其是Laravel Sanctum下动态设置SESSION_DOMAIN以及Octane的影响,我整理了一套可行的解决方案,咱们一步步来看:
一、动态设置Session与Sanctum Cookie域名的正确姿势
你之前尝试的Config::set()没生效,是因为Sanctum的Cookie配置不仅依赖session.domain,还有自身独立的sanctum.cookie.domain配置,而且需要在请求生命周期的早期就完成设置,才能被Session和Sanctum组件识别。
实现步骤:
创建全局中间件
新建一个中间件SetDynamicSessionDomain,用来根据当前请求的域名动态调整配置:<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Config; class SetDynamicSessionDomain { public function handle($request, Closure $next) { $host = $request->getHost(); $targetDomain = null; // 根据请求域名匹配对应的Cookie根域名 if (str_ends_with($host, '.my-domain.com')) { $targetDomain = '.my-domain.com'; // 子域名共享Cookie } elseif ($host === 'company.com') { $targetDomain = '.company.com'; // 自定义顶级域名的Cookie } if ($targetDomain) { // 同步设置Session和Sanctum的Cookie域名 Config::set('session.domain', $targetDomain); Config::set('sanctum.cookie.domain', $targetDomain); // 确保当前请求域名在Sanctum的stateful列表中(避免无状态判定) $statefulDomains = Config::get('sanctum.stateful'); if (!in_array($host, $statefulDomains)) { $statefulDomains[] = $host; Config::set('sanctum.stateful', $statefulDomains); } } return $next($request); } }注册中间件
在app/Http/Kernel.php的$middleware数组最顶部注册这个中间件,确保它在Session和Sanctum的中间件之前执行:protected $middleware = [ \App\Http\Middleware\SetDynamicSessionDomain::class, // 其他中间件... ];
二、Octane环境下的配置污染问题处理
Octane的常驻进程模式会导致请求间的配置被复用,如果直接动态修改Config,后续请求会继承上一次的配置,引发域名混乱。解决方法是利用Octane的请求钩子,在每个请求开始前重置配置:
在config/octane.php的hooks数组中添加前置重置逻辑:
'hooks' => [ 'beforeRequest' => [ function () { // 重置为.env中的初始配置,确保每个请求开始时配置干净 Config::set('session.domain', env('SESSION_DOMAIN', null)); Config::set('sanctum.cookie.domain', env('SESSION_DOMAIN', null)); Config::set('sanctum.stateful', explode(',', env('SANCTUM_STATEFUL_DOMAINS', ''))); }, ], // 其他钩子... ],
这样每个请求都会先重置配置,再通过中间件设置当前请求对应的域名,避免跨请求的配置污染。
三、额外注意事项
- CSRF验证:确保前端能正确获取到
XSRF-TOKENCookie,动态设置域名后,Cookie的作用域正确,前端才能读取并在请求头中携带X-XSRF-TOKEN。 - Cookie SameSite属性:如果自定义域名(如company.com)和API域名(api.company.com)是跨顶级域名场景,需要将
session.same_site设置为'none',同时开启session.secure = true(仅HTTPS环境有效),否则Cookie无法跨域传递。 - 测试覆盖:一定要分别测试
company.my-domain.com和company.com两种场景,验证Cookie域名是否正确、认证流程是否顺畅,以及跨域请求是否被允许。
内容的提问来源于stack exchange,提问作者nader ghazi
相关产品推荐
相关产品推荐

