Laravel Sanctum如何配置无需逐个添加域名即可向任意域发会话Cookie
前置说明
Sanctum默认的stateful配置仅支持精确域名匹配,原生不支持*通配符,因此直接填写通配符不会生效。以下配置方案可实现无需逐个添加域名的需求:
步骤1:配置信任反向代理
因为应用部署在反向代理后,首先需要让Laravel正确识别原始请求信息:
打开app/Http/Middleware/TrustProxies.php,修改如下:
<?php namespace App\Http\Middleware; use Illuminate\Http\Request; use Illuminate\Http\Middleware\TrustProxies as Middleware; class TrustProxies extends Middleware { // 允许所有代理访问,生产环境建议填写实际反向代理IP段以提升安全性 protected $proxies = '*'; // 读取代理传递的所有转发头 protected $headers = Request::HEADER_X_FORWARDED_ALL; }
步骤2:两种配置方案二选一
方案A:动态匹配请求Origin域名(安全度更高)
无需修改Sanctum核心逻辑,仅调整配置文件即可:
- 修改
config/sanctum.php的stateful配置:
'stateful' => array_merge( explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1')), // 动态将当前请求的Origin域名加入可信任列表 request()->headers->get('Origin') ? [parse_url(request()->headers->get('Origin'), PHP_URL_HOST)] : [] ),
- 调整CORS配置(
config/cors.php):
return [ 'paths' => ['api/*', 'sanctum/csrf-cookie'], 'allowed_methods' => ['*'], // 动态匹配请求Origin,避免使用通配符导致凭证不生效 'allowed_origins' => [request()->headers->get('Origin') ?? env('APP_URL', 'http://localhost')], 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, // 必须开启,允许跨域携带Cookie 'supports_credentials' => true, ];
方案B:完全跳过域名校验(更灵活,适合内部多域名场景)
直接重写Sanctum的域名检查逻辑,无需维护域名列表:
- 生成自定义中间件:
php artisan make:middleware CustomEnsureStatefulRequests
- 编辑中间件文件
app/Http/Middleware/CustomEnsureStatefulRequests.php:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful; class CustomEnsureStatefulRequests extends EnsureFrontendRequestsAreStateful { public function handle(Request $request, Closure $next) { // 仅对符合路径规则的前端请求跳过域名校验,直接开启状态化会话 if ($this->isFrontendRequest($request)) { return $this->addSecureHeaders($next($request), $request); } return $next($request); } }
- 替换内核中间件,打开
app/Http/Kernel.php,修改api中间件组:
protected $middlewareGroups = [ 'api' => [ // 注释掉原有Sanctum的状态校验中间件 // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, // 替换为自定义中间件 \App\Http\Middleware\CustomEnsureStatefulRequests::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ];
步骤3:配置会话Cookie属性
打开config/session.php,调整跨站Cookie生效规则:
// 生产环境必须开启HTTPS,此处设为true 'secure' => env('SESSION_SECURE_COOKIE', true), // 跨站场景必须设为none,才能被第三方域名携带 'same_site' => 'none', 'http_only' => true,
前端配合要求
所有请求必须开启凭证携带:
- Axios配置:
axios.defaults.withCredentials = true - Fetch配置:
fetch(url, { credentials: 'include' }) - 请求接口前必须先调用
/sanctum/csrf-cookie接口获取CSRF令牌,Sanctum会自动将令牌写入Cookie,后续请求会自动携带X-XSRF-TOKEN头
安全提示
允许任意域名携带会话Cookie存在CSRF风险,生产环境建议根据业务情况增加域名校验逻辑,避免恶意站点发起跨站请求伪造攻击。
内容的提问来源于stack exchange,提问作者Nick M
相关产品推荐
相关产品推荐

