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

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