$request->ip() 默认返回代理IP而非真实客户端IP,因Laravel不信任代理头,需配置TrustProxies中间件指定可信代理IP并设置X-Forwarded-For等头字段。

直接用 $request->ip() 判断白名单,90% 的情况会失效——它在 Nginx、Cloudflare 或 ALB 后面默认返回代理 IP,不是真实客户端 IP。
为什么 $request->ip() 拿不到真实 IP
根本原因是 Laravel 默认不信任任何代理头。哪怕 Nginx 已配置 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for,Laravel 仍会忽略 X-Forwarded-For,只返回 $_SERVER['REMOTE_ADDR'](通常是 127.0.0.1 或内网地址)。
- 必须显式设置可信代理:在
app/Http/Middleware/TrustProxies.php中填入你的反代真实出口 IP,比如protected $proxies = ['127.0.0.1', '10.0.0.0/8']; - 漏配
TRUSTED_PROXIES环境变量或$proxies数组,$request->ip()就永远不准 - Cloudflare 用户额外加
'CF-Connecting-IP'到TrustProxies::$header,否则拿不到真实 IPv4/IPv6 - 本地开发时
php artisan serve不走 Nginx,$request->ip()是127.0.0.1,白名单里得包含它,否则 CLI 测试直接 403
白名单中间件怎么写才可靠
别套“校验 → 放行 → next”模板,重点是早拦截、少依赖、防空值。
- 构造函数里读配置:
config('ip-whitelist.allowed', []),不要硬编码数组 - handle() 开头就取 IP:
$ip = $request->ip() ?: $request->server('REMOTE_ADDR');,防止空值崩溃 - 用
filter_var($ip, FILTER_VALIDATE_IP)先校验格式,避免字符串注入或解析错误 - CIDR 匹配不能靠
in_array():写个轻量ip_in_range($ip, $cidr)函数,支持192.168.1.0/24和2001:db8::/32 - 匹配失败立刻返回:
return response('', 403)->header('X-Content-Type-Options', 'nosniff');,别用abort(403)(跳过后续中间件且无法加响应头)
白名单配置放哪最稳
放 .env 或 config/app.php 都不合适——前者难写数组,后者污染主配置。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
- 新建
config/ip-whitelist.php,内容为:return [ 'allowed' => explode(',', env('IP_WHITELIST', '127.0.0.1')), ]; - 环境变量写法:
IP_WHITELIST=192.168.1.10,203.0.113.5,10.0.0.0/8 - 测试时可直接改 PHP 数组,不用动环境变量,CI/CD 也方便注入
- 别查数据库加载白名单——每次请求都查库,扛不住压测;缓存用
Cache::rememberForever('ip-whitelist', fn() => config('ip-whitelist.allowed'))
中间件注册顺序和调试要点
挂错位置等于没写。常见现象是写了中间件但请求压根没进逻辑,或者 403 是 Nginx 报的而不是你返回的。
- 必须注册到
$middleware全局栈(不是$middlewareGroups),确保所有请求都经过 - 顺序要放在
TrustProxies::class之后、EncryptCookies::class之前——早于 Session 启动,避免无谓开销 - 调试时在 handle() 开头加:
Log::warning('IP check', ['ip' => $request->ip(), 'raw' => $request->server('REMOTE_ADDR')]); - 如果日志没输出,说明中间件根本没注册成功,检查
app/Http/Kernel.php是否拼错类名或命名空间 - 线上别用
dd(),用日志 + Network 面板看响应状态码和 headers 是否是你写的
真正麻烦的从来不是写几行判断逻辑,而是搞清 IP 怎么来、谁在转发、头被谁改过、日志往哪打——这些细节一错,白名单就形同虚设。










