MineAdmin 交流群

官方QQ群: 150105478

Skip to content

获取客户端Ip

WARNING

mineadmin/support >= 3.0.21

在记录用户操作记录的中间件中,会在每次请求时记录用户的访问记录。其中包括了用户 ip 地址。 而获取客户端 ip,是由 Support 组件中的 ClientIpRequestTrait 封装而来的。此处则直接借鉴了 symfony Request 的实现方法。

而由于在生产环境中,一般来说还会会套一层或多层反向代理。这样如果不设置受信任的代理时。则会获取到真实的反向代理 ip。以下将简单介绍下如何在反向代理后的程序中获取正确的客户端 ip 而不是局域网地址

新建一个 app/Http/Common/Listener/SetRequestTrustedProxiesListener 文件

php
<?php

<?php
namespace App\Http\Common\Listener;

use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;
use Hyperf\Framework\Event\BootApplication;
use Mine\Support\Request;
use Mine\Support\Request\ClientIpRequestConstant;

#[Listener]
class SetRequestTrustedProxiesListener implements ListenerInterface{

    public function listen(): array
    {
        // 监听应用启动事件
        // 以便在应用启动时设置受信任的代理
        // 这将确保在处理请求之前设置受信任的代理
        // 以便正确处理客户端 IP 地址
        return [
            BootApplication::class,
        ];
    }

    public function process(object $event): void
    {
        /**
         * 设置受信任的代理
         * 第一个参数是受信任的代理 IP 地址或 CIDR 范围
         * 这里的 'PRIVATE_SUBNETS' 应该替换为实际的私有子网 IP 地址或 CIDR 范围
         * 在 Symfony\Component\HttpFoundation\IpUtils::PRIVATE_SUBNETS 中定义了可信任的网段
         * 第二个参数是用于获取客户端 IP 地址的请求头
         * 这里使用了 ClientIpRequestConstant::HEADER_X_FORWARDED_FOR
         * 这将在处理请求时使用 X-Forwarded-For 头来获取客户端 IP 地址
         */
        Request::setTrustedProxies(['PRIVATE_SUBNETS'],ClientIpRequestConstant::HEADER_X_FORWARDED_FOR);
    }
}

再在反向代理配置,以 nginx 为例,配置 x-forwarded-for 请求头

conf

#PROXY-START/

location ^~ /
{
    proxy_pass http://127.0.0.1:55502//;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Real-IP $proxy_add_x_forwarded_for;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_http_version 1.1;
    # proxy_hide_header Upgrade;

    add_header X-Cache $upstream_cache_status;
    #Set Nginx Cache

    set $static_filephG5rYEX 0;
    if ( $uri ~* "\.(gif|png|jpg|css|js|woff|woff2)$" )
    {
        set $static_filephG5rYEX 1;
        expires 1m;
    }
    if ( $static_filephG5rYEX = 0 )
    {
        add_header Cache-Control no-cache;
    }
}
#PROXY-END/

即可正确获取到客户端真实 ip

致力于为品牌和企业创造价值