关于 Laravel 使用了 CDN 获取真实 IP 记录

简述:

获取 laravel 使用 cdn 后 获取用户的真实 ip

可以设置 TrustProxies 中间件 来设置 信任代理 ip 和代理头。
不过在 laravel 里面只能设置这些 。

关于Laravel 使用了CDN 获取真实IP记录

一般我们获取 cdn 或者 反向代理 都是通过这个 HEADER_X_FORWARDED_FOR 头来获取的。
ip 的格式为:clientip,proxy1,proxy2。第一个就是客户端的 ip

TrustProxies 中间件的配置

/**
     * The trusted proxies for this application.
     *
     * @var array|string
     * 这里填反向代理的ip,支持填IP段
     */
    protected $proxies = "
        '127.0.0.1/24'
    ";
    /**
     * The headers that should be used to detect proxies.
     * 这里填用来检测 ip 代理的头部
     * @var int
     */
    protected $headers = Request::HEADER_X_FORWARDED_FOR;

proxies 设置反向代理的 ip 或者 cdnip段,虽然可以填 * 号,但是我测试的时候获取的还是 cdnip
获取 ip 可以通过 Request 类,它也有辅助函数。

$request->ip();
$request->getClientIp();
request()->ip();
request()->getClientIp()
/** 这几个方法都可以获取客户端的 ip **/

$request->ip() 方法是通过 $request->getClientIp() 方法获取的
而 $request->getClientIps() 方法获取的。

这里说一下(我测试的时候) 如果 proxies 设置为 * 的话
通过 $request->getClientIp() 来获取ip,获取的是 CDNip
通过 $request->getClientIps() 获取的结果

array:3 [▼
  0 => "proxy1ip"
  1 => "proxy2ip"
  2 => "clientIp"
]

而我通过 $_SERVER['HTTP_X_FORWARDED_FOR'] 打印出来的是,与 getClientIps 获取的结果正好相反。

array:3 [▼
  0 => "clientIp"
  1 => "proxy2ip"
  2 => "proxy1ip"
]

看一下 getClientIp 的代码,它获取的是 getClientIps 的第一个ip.
正常来说,第一个ip应该是客户端的ip的,但是 getClientIps 把结果翻转过来了,我这里 laravle 版本是 5.8 不知道其他版本是不是这样。
关于Laravel 使用了CDN 获取真实IP记录

更多 proxies 说明可以看这里 https://symfony.com/doc/current/deployment...

关于 Laravel 使用了 CDN 获取真实 IP 记录

如果 cdn 可以自定义真实ip头的话,就可以在 /public/index.php 文件来替换TrustProxies设置的header

ps:第一次发文章,写的不好请见谅😀

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 2
Summer

自定义 TrustProxies 的 header 可以看这里,不应该修改 index.php:

全局中间件之 TrustProxies

1周前 评论

@Summer 自定义 TrustProxies 的 header,我设置的是 Request::HEADER_X_FORWARDED_FOR;
但是通过 getClientIp() 获取的还是 cdn 的ip,除非我把所有的 ip 段加入信任代理, 因为这个获取的是 getClientIps() 的第一个元素。
然而我通过 getClientIps()$_SERVER['HTTP_X_FORWARDED_FOR'] 打印出来的数据顺序正好是相反的。
getClientIps() 的 最后一个元素才是真实的 ip

也有可能是我 cdn 问题吧。现在用的是百度 cdn ,以前用腾讯云 cdn 的时候可以获取到真实 ip ,也会获取到 cdn ip 。

1周前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!