laravel-cors 进阶用法:按登录用户动态放行域名,自定义 CORS Profile 实战(附完整代码)

📅 2026/8/27 17:38:04
laravel-cors 进阶用法:按登录用户动态放行域名,自定义 CORS Profile 实战(附完整代码)
laravel-cors 进阶用法按登录用户动态放行域名自定义 CORS Profile 实战附完整代码【免费下载链接】laravel-corsSend CORS headers in a Laravel application项目地址: https://gitcode.com/gh_mirrors/lara/laravel-corslaravel-cors 是 Laravel 生态中专门用于给接口响应添加 CORS 跨域请求头的开源包。本文带你掌握它的进阶能力——自定义 CORS Profile不再写死配置文件里的域名白名单而是根据当前登录用户动态决定放行哪些源适合多租户 SaaS 场景。为什么需要自定义 CORS Profile默认情况下config/cors.php 里的allow_origins是一张全局静态白名单对所有用户一视同仁。但如果你做的是 SaaS 或多租户产品更常见的诉求是用户 A 绑定了https://a.example.com只允许它跨域访问 API用户 B 绑定了https://b.example.com只放行它自己的域名请求来源不在当前用户的授权列表里 → 直接返回 403这时DefaultProfile就不够用了需要写一个自己的 Profile。快速上手安装与注册中间件通过 Composer 安装composer require spatie/laravel-cors 国内用户也可以 clone 镜像仓库到本地再安装git clone https://gitcode.com/gh_mirrors/lara/laravel-cors然后把中间件注册到全局中间件组src/Cors.php 就是这个中间件的核心// app/Http/Kernel.php protected $middleware [ ... \Spatie\Cors\Cors::class, ];最后发布配置文件php artisan vendor:publish --providerSpatie\Cors\CorsServiceProvider --tagconfig默认 Profile 是怎么工作的配置项cors_profile决定了使用哪个 Profile 类默认值是DefaultProfile它的所有行为允许的源、方法、请求头、max_age等都直接读取 config/cors.php 中的default_profile配置。关键的放行判断在 src/CorsProfile/DefaultProfile.php 的isAllowed()方法请求方法不在allow_methods里 → 拒绝白名单包含*→ 放行所有源否则用fnmatch把Origin请求头和白名单逐条做通配符匹配所以https://*.spatie.be这种子域名通配是支持的中间件的完整处理流程见 src/Cors.php非跨域请求直接放行不满足 Profile 的返回 403文案和状态码可在forbidden_response里自定义OPTIONS预检请求直接返回 204 并附带预检头普通请求则在响应上追加 CORS 头。核心实战按登录用户动态放行域名第一步创建自定义 ProfileProfile 本质上就是继承DefaultProfile后重写你关心的方法。假设你的用户表里已有allowed_domains字段json 类型完整代码如下// app/Services/Cors/UserBasedCorsProfile.php namespace App\Services\Cors; use Illuminate\Support\Facades\Auth; use Spatie\Cors\CorsProfile\DefaultProfile; class UserBasedCorsProfile extends DefaultProfile { public function allowOrigins(): array { return Auth::user()-allowed_domains ?? []; } }就这么简单 你只需重写allowOrigins()其余方法凭据、方法、请求头……全部沿用默认配置。想改行为时可以重写 src/CorsProfile/CorsProfile.php 接口定义中的任意方法例如public function allowCredentials(): bool { // 需要携带 Cookie/Token 时必须为 true return true; } public function maxAge(): int { return 60 * 60 * 24; // 预检请求缓存时长秒 }第二步在配置中注册你的 Profile// config/cors.php cors_profile App\Services\Cors\UserBasedCorsProfile::class,⚠️ 注意src/CorsServiceProvider.php 启动时会校验你配置的 Profile必须是DefaultProfile的子类否则抛出InvalidCorsProfile异常定义见 src/Exceptions/InvalidCorsProfile.php。所以请继承不要从零实现接口。请求放行效果一览场景结果请求源在用户allowed_domains中✅ 正常响应 CORS 头请求源不在授权列表中⛔ 返回 403Forbidden (cors).预检OPTIONS请求返回 204 预检头Allow-Origin/Methods/Headers/Max-Age请求没带Origin头同源请求不做任何处理直接放行一个小细节当allow_credentials为true时Access-Control-Allow-Origin不会返回*而是原样回显请求的Origin见 src/CorsProfile/DefaultProfile.php这是浏览器规范的要求用户级动态放行天然契合这一点。常见问题与注意事项Laravel 版本作者已宣布该包停止维护因为 Laravel 7 起自带原生 CORS 支持。如果你用的是 Laravel 7 及以上版本请优先使用框架内置的cors.php配置本包适用于 Laravel 6 及以下的老项目见 CHANGELOG.md 与 README 的 Notice。未登录怎么办如果存在匿名接口在allowOrigins()里对Auth::user()为空的情况兜底比如返回一个公共白名单避免 NPE。通配符allowed_domains里存https://*.a.example.com同样生效底层就是fnmatch匹配。想快速验证行为可参考 tests/DefaultProfileTest.php 的测试写法用config()-set()动态改配置即可断言 Profile 行为。小结laravel-cors 的设计很干净中间件负责流程Profile 负责策略。写一个继承DefaultProfile的类、重写allowOrigins()、改一行配置就能实现每个登录用户只放行自己的域名——这正是它相比纯配置文件方案的杀手级特性。掌握这个扩展点你就有能力应对绝大多数动态跨域授权需求 【免费下载链接】laravel-corsSend CORS headers in a Laravel application项目地址: https://gitcode.com/gh_mirrors/lara/laravel-cors创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考