laravel需配置trustproxies中间件以正确获取真实客户端ip:设$proxies为代理ip段(如['127.0.0.1']或cloudflare网段),$headers包含header_x_forwarded_for;origin仅作快速过滤,不可用于鉴权;referer更不可靠,仅辅助业务判断;真正可靠的是api key等应用层凭证。

如何用 TrustProxies 处理跨域请求来源判断
Laravel 本身不校验请求的 Origin 或 Referer,它默认信任所有来源;真正起作用的是中间件和底层 HTTP 层对代理头的解析。如果你发现 request()->ip() 返回 127.0.0.1 或内网地址,大概率是反向代理(Nginx / Cloudflare)没配好,导致 Laravel 拿不到真实客户端 IP,后续基于 IP 或域名的验证全失效。
关键在 App\Http\Middleware\TrustProxies 类里配置 $proxies 和 $headers:
- 若用 Nginx 直连 PHP-FPM,通常只需设
$proxies = ['127.0.0.1']; - 若走 Cloudflare 或多层代理,得填实际代理 IP 段,比如
['103.21.244.0/22', '173.245.48.0/20'](参考 Cloudflare 官方 IP 列表) - 务必确认
$headers包含Illuminate\Http\Request::HEADER_X_FORWARDED_FOR,否则request()->ip()不会读X-Forwarded-For
手动校验 Origin 头是否合法
浏览器发 CORS 请求时会带 Origin 头,但这个头可被任意篡改——服务端不能只靠它做权限控制,但它适合快速拦截明显非法调用(比如非预期域名直接访问接口)。别把它当安全边界,只当第一道过滤。
示例:在中间件里检查
if (! in_array(request()->header('Origin'), ['https://a.com', 'https://b.net'])) {
abort(403, 'Origin not allowed');
}
注意点:
-
Origin值不含路径,只有协议+域名+端口(如https://a.com:8080),匹配时要完整一致 - 非 CORS 请求(如普通表单提交、curl)不会带
Origin,此时该头为空字符串,需额外判断request()->header('Origin') !== '' - 开发环境本地启前端(
http://localhost:3000)要显式加入白名单,否则连调试都过不去
用 Referer 辅助识别页面来源(慎用)
Referer 比 Origin 更不可靠:HTTP 规范允许浏览器不发、可伪造、HTTPS 页面跳转到 HTTP 时会被自动清空。但它在某些后台管理场景下仍有用——比如限制「只能从 /admin/dashboard 页面发起的导出请求」。
实操建议:
- 只用于业务逻辑辅助判断,绝不用于鉴权或敏感操作放行
- 用
parse_url(request()->header('Referer'), PHP_URL_HOST)提取域名,避免正则误匹配路径 - 如果后端 API 被 Postman、脚本调用,
Referer默认不存在,得加兜底逻辑(比如配合 token 或签名)
真正可靠的来源控制得靠应用层凭证
IP 白名单、Origin、Referer 全是 HTTP 层的“软约束”,绕过成本极低。生产环境真正可控的方式是:每个调用方分配独立 api_key,绑定域名/IP/用途,在中间件里查库或 Redis 验证有效性。
例如:
if (! Cache::has('api_key:'.$request->bearerToken())) {
abort(401);
}
容易忽略的细节:
- API Key 必须通过
Authorization: Bearer xxx传递,不能拼在 URL 或 body 里(日志、代理可能泄露) - 域名绑定要支持泛解析(
*.example.com),否则子域名迭代时频繁改配置 - 一旦用上凭证机制,就别再依赖
Origin做主校验——它只是锦上添花,不是基石











