Laravel 13 通过 config/cors.php 的 allowed_origins_patterns 字段支持正则匹配动态子域名(如 *.example.com),需清空 allowed_origins 并设 supports_credentials => true,正则确保安全匹配合法子域且响应头精确回写实际来源。

Laravel 13 默认使用 fruitcake/laravel-cors(已深度集成,无需额外安装),其 config/cors.php 支持 allowed_origins_patterns 字段,专用于通过正则表达式匹配动态子域名——这是解决 *.example.com 类跨域需求的安全且推荐方式,避免硬编码所有子域或误用 *(尤其开启 supports_credentials => true 时)。
✅ 正确配置 allowed_origins_patterns 允许所有子域名
在 config/cors.php 中:
'allowed_origins_patterns' => [
'^https?://(?:[a-z0-9\-]+\.)?example\.com(:[0-9]+)?$',
],
'allowed_origins' => [], // 必须清空,否则 patterns 不生效
'supports_credentials' => true,
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_headers' => ['Content-Type', 'Authorization', 'X-Requested-With'],
? 正则说明:
^https?://→ 匹配http://或https://(?:[a-z0-9\-]+\.)?→ 可选的子域名前缀(如api.、app.、staging.),支持连字符和数字example\.com→ 主域名(注意转义点号)(:[0-9]+)?→ 可选端口(开发时 localhost:3000 也能匹配)$→ 字符串结尾,防意外匹配(如evil-example.com)
✅ 示例匹配:
-
https://example.com✔️ -
http://www.example.com✔️ -
https://api.example.com:8080✔️ -
http://staging.example.com✔️
❌ 不匹配: -
https://example.org❌ -
https://evil-example.com❌ -
https://example.com.evil.com❌
⚠️ 关键注意事项
-
allowed_origins必须为空数组([]),否则patterns被忽略 - 若启用了
supports_credentials => true(如需 Cookie 或 Authorization),*绝不能同时设 `allowed_origins => ['']`**,否则浏览器直接拒绝 - 修改后务必运行:
php artisan config:clear
- 浏览器对
Access-Control-Allow-Origin的响应头只接受单个值,正则匹配成功后,Laravel 会将实际请求来源域名原样回写到该响应头(不是通配符),满足凭证请求要求
? 验证是否生效
前端发起带凭据请求时(如 Axios):
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
axios.get('/api/user', {
withCredentials: true // 必须开启
})
检查 Network 面板响应头:
-
Access-Control-Allow-Origin: https://app.example.com(与请求 Origin 完全一致) -
Access-Control-Allow-Credentials: true - 无
Access-Control-Allow-Origin: *(那是错误信号)
? 补充:多主域名 + 子域场景
若还需支持 example.cn 和其子域,追加另一条正则:
'allowed_origins_patterns' => [
'^https?://(?:[a-z0-9\-]+\.)?example\.com(:[0-9]+)?$',
'^https?://(?:[a-z0-9\-]+\.)?example\.cn(:[0-9]+)?$',
],
不复杂但容易忽略。










