43 lines
1.5 KiB
PHP
43 lines
1.5 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Middleware;
|
||
|
||
use Closure;
|
||
use Illuminate\Http\Request;
|
||
use Symfony\Component\HttpFoundation\Response;
|
||
|
||
class CloudflareProxies
|
||
{
|
||
/**
|
||
* 文件功能:强制信任并解析 CDN 传导的真实客户端 IP。
|
||
* 解决 Herd 环境 / Nginx 本地反代时,丢失 X-Forwarded-For 导致全员 IP 变成 127.0.0.1 的问题。
|
||
*/
|
||
public function handle(Request $request, Closure $next): Response
|
||
{
|
||
// 优先采纳 Cloudflare 的 CF-Connecting-IP
|
||
if ($request->hasHeader('CF-Connecting-IP')) {
|
||
$realIp = $request->header('CF-Connecting-IP');
|
||
}
|
||
// 腾讯云 EdgeOne CDN 自定义回源头部(后台配置名:EO-Client-IP)
|
||
elseif ($request->hasHeader('EO-Client-IP')) {
|
||
$realIp = $request->header('EO-Client-IP');
|
||
}
|
||
// 其他国内 CDN 厂商(阿里云 DCDN 等)通用头部
|
||
elseif ($request->hasHeader('X-Real-IP')) {
|
||
$realIp = $request->header('X-Real-IP');
|
||
}
|
||
// 最后兜底:取 X-Forwarded-For 最左边第一个(真实客户端)IP
|
||
// 格式为 "真实客户端, CDN节点1, CDN节点2"
|
||
elseif ($request->hasHeader('X-Forwarded-For')) {
|
||
$realIp = trim(explode(',', $request->header('X-Forwarded-For'))[0]);
|
||
}
|
||
|
||
if (! empty($realIp)) {
|
||
$request->server->set('REMOTE_ADDR', $realIp);
|
||
$request->headers->set('X-Forwarded-For', $realIp);
|
||
}
|
||
|
||
return $next($request);
|
||
}
|
||
}
|