Referer 验证不推荐在 Laravel 中直接使用,因其可被客户端伪造且浏览器可能不发送或仅发源站域名,无法替代身份认证;应优先采用 CORS + 凭据 + Token 等组合策略实现真正防护。

Referer 验证在 Laravel 中不推荐直接做
因为 Referer 是客户端可随意伪造的 HTTP 头,且现代浏览器(尤其启用了 Referrer-Policy: strict-origin-when-cross-origin 或 no-referrer 的场景)可能根本不发、或只发源站域名,导致合法请求被误拒。它不能替代身份认证或权限控制。
如果你只是想防止「别人把你的 API 地址复制到自己页面里用 JS 直接调」,那 Referer 检查确实能拦住一部分懒人,但对真正想绕过的人毫无意义——他们用 Postman、curl、甚至服务端代理都能轻松绕过。
Laravel 中如何读取和简单校验 Referer
Laravel 通过 request()->headers->get('referer') 获取原始值(注意拼写是 referer,不是 referrer),但必须注意:该值可能为空、格式不规范、含端口、带路径,甚至包含用户可控参数。
- 永远用
parse_url()解析后再比对域名,不要用str_contains()或strpos()直接搜字符串 - 校验时只比对
host,忽略scheme(HTTP/HTTPS 混用常见)、port(80/443 可省略)、path(前端路由可能带 hash 或 query) - 允许白名单多个域名,比如
['myapp.com', 'staging.myapp.com'],别硬编码进中间件 - 线上环境建议加日志记录非法 Referer,但别暴露敏感信息(如完整 URL)
示例判断逻辑:
if ($referer = request()->headers->get('referer')) {
$parsed = parse_url($referer);
if ($parsed && isset($parsed['host']) && !in_array($parsed['host'], ['myapp.com', 'staging.myapp.com'])) {
abort(403, 'Invalid referer');
}
}
更靠谱的替代方案:用 CORS + 凭据 + Token
Referer 校验本质是「前端来源管控」,而真正该做的,是让前端只能在你自己的域名下发起合法请求。这靠的是组合策略:
- CORS 配置中设置
Access-Control-Allow-Origin为具体域名(如https://myapp.com),禁用通配符*;同时开启credentials: true - 前端请求带上
withCredentials: true,后端响应头加Access-Control-Allow-Credentials: true - 关键接口要求登录态(如
Authorization: Bearer xxx或 session cookie),且 cookie 设置SameSite=Lax或Strict - 必要时加一次性 token(如从服务端渲染的 HTML 中注入
data-csrf-token),验证后再放行
这样即使 Referer 被伪造,没有有效凭证或跨域权限,请求也进不来。
中间件里写 Referer 校验容易踩的坑
很多人把 Referer 校验写成全局中间件,结果连健康检查、队列任务触发、Webhook 回调都卡住了——这些请求压根没有 Referer 头。
- 不要在
Kernel.php的$middleware全局数组里注册 Referer 中间件 - 只在明确需要的路由组里用
middleware属性绑定,例如:Route::middleware(['check_referer'])->group(...) - 测试时用
curl -H "Referer: https://evil.com"模拟,别只依赖浏览器 F12 发请求 - 如果用了 CDN 或反向代理(如 Nginx),确认
Referer头没被过滤或覆盖(检查proxy_set_header Referer $http_referer;)
Referer 验证不是安全边界,而是个松散的“前端使用提示”。真要防滥用,得靠鉴权、限流、签名、IP 白名单这些实打实的机制。


















