IT

Larabel 5+에서 클라이언트 IP 주소를 얻는 방법

itgroup 2023. 1. 1. 11:10
반응형

Larabel 5+에서 클라이언트 IP 주소를 얻는 방법

저는 라라벨에 있는 클라이언트의 IP 주소를 얻으려고 합니다.

「PHP」의 「IP」를 로 수.$_SERVER["REMOTE_ADDR"]코어 PHP에서는 정상적으로 동작하고 있습니다만, Laravel에서도 같은 것을 사용하면 방문자의 IP가 아닌 서버 IP가 반환됩니다.

Laravel API 보기:

Request::ip();

「이러다」, 「이러다」, 「이러다」, 「이러다」, 「이러다만,getClientIpsSymfony 요청 개체의 메서드:

public function getClientIps()
{
    $clientIps = array();
    $ip = $this->server->get('REMOTE_ADDR');
    if (!$this->isFromTrustedProxy()) {
        return array($ip);
    }
    if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) {
        $forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]);
        preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches);
        $clientIps = $matches[3];
    } elseif (self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) {
        $clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
    }
    $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from
    $ip = $clientIps[0]; // Fallback to this when the client IP falls into the range of trusted proxies
    foreach ($clientIps as $key => $clientIp) {
        // Remove port (unfortunately, it does happen)
        if (preg_match('{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) {
            $clientIps[$key] = $clientIp = $match[1];
        }
        if (IpUtils::checkIp($clientIp, self::$trustedProxies)) {
            unset($clientIps[$key]);
        }
    }
    // Now the IP chain contains only untrusted proxies and the client IP
    return $clientIps ? array_reverse($clientIps) : array($ip);
} 

밸런서 , 의 「Laravel 「Laravel」\Request::ip() 는 항상 밸런서의 IP를 반환합니다.

            echo $request->ip();
            // server ip

            echo \Request::ip();
            // server ip

            echo \request()->ip();
            // server ip

            echo $this->getIp(); //see the method below
            // clent ip

이 커스텀 메서드는 실제 클라이언트 IP를 반환합니다.

public function getIp(){
    foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
        if (array_key_exists($key, $_SERVER) === true){
            foreach (explode(',', $_SERVER[$key]) as $ip){
                $ip = trim($ip); // just to be safe
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
                    return $ip;
                }
            }
        }
    }
    return request()->ip(); // it will return server ip when no client ip found
}

또한 Larabel의 스로틀 미들웨어를 사용할 때는 매우 주의할 것을 권장합니다.Laravel's를 사용합니다.Request::ip()또한 모든 방문자가 동일한 사용자로 식별되고 스로틀 제한에 매우 빠르게 도달합니다.저는 이 라이브를 경험해서 큰 문제를 일으켰습니다.

이 문제를 해결하려면:

조명\Http\Request.php

    public function ip()
    {
        //return $this->getClientIp(); //original method
        return $this->getIp(); // the above method
    }

아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 이런Request::ip()IP를 사용하다

request()->ip()

제가 알기로는 Larabel 5부터는 다음과 같은 글로벌 기능을 사용하는 것이 좋습니다.

response()->json($v);
view('path.to.blade');
redirect();
route();
cookie();

또한 정적 표기법 대신 함수를 사용할 경우 IDE가 크리스마스 트리처럼 켜지지 않습니다.

네임스페이스 추가

use Request;

그러면 함수를 호출합니다.

Request::ip();

Larabel 5의 요청입니다. 냥 its just just its its just just just just 。ip()예를 들어 다음과 같습니다.

$request->ip();

다음 두 가지 사항을 고려해야 합니다.

  1. 는 를반 a a a a a a a a a a를 하는 기능을 .Illuminate\Http\Request '불러주세요.->ip()★★★★

    request()->ip();
    
  2. 에 대해 또는 「」를 할 수 .프록시 또는load-balancerAWS ELB는 AWS ELB를 사용합니다.

이 경우 "신뢰할 수 있는 프록시 구성"을 따르거나 "모든 프록시 신뢰" 옵션을 설정해야 합니다.

요?를 입니다. 왜냐하면 당신의 서버가 되는 것은 당신의 프록시를 얻기 때문입니다.load-balancer【IP】

AWS 는, AWS 의 URL 에 해 .App\Http\Middleware\TrustProxies 만들어 내다$proxies을 사용하다

protected $proxies = '*';

츠미야 스로틀 미들웨어로 인해 어려움을 겪지 않으셨기 때문입니다. ,에 합니다.request()->ip() "않으면이 아니라 할 수 .

또한 설명서에 스로틀 미들웨어가 제대로 설명되어 있지 않기 때문에 "초급자를 위한 larabel 5.2 튜토리얼, API Rate Limiting"을 보는 것을 추천합니다.

Larabel 5.7에서 테스트 완료

인 라라벨 5

public function index(Request $request) {
  $request->ip();
}

Laravel 8.x에서 테스트를 실시했습니다.다음 항목을 사용할 수 있습니다.

$request->ip()

클라이언트의 IP 주소를 취득합니다.

아래 함수는 클라이언트의 IP 주소를 제공하는 데 도움이 됩니다.

public function getUserIpAddr(){
       $ipaddress = '';
       if (isset($_SERVER['HTTP_CLIENT_IP']))
           $ipaddress = $_SERVER['HTTP_CLIENT_IP'];
       else if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
           $ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
       else if(isset($_SERVER['HTTP_X_FORWARDED']))
           $ipaddress = $_SERVER['HTTP_X_FORWARDED'];
       else if(isset($_SERVER['HTTP_FORWARDED_FOR']))
           $ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
       else if(isset($_SERVER['HTTP_FORWARDED']))
           $ipaddress = $_SERVER['HTTP_FORWARDED'];
       else if(isset($_SERVER['REMOTE_ADDR']))
           $ipaddress = $_SERVER['REMOTE_ADDR'];
       else
           $ipaddress = 'UNKNOWN';    
       return $ipaddress;
    }

Laravel 5.4에서는 ip static이라고 할 수 없습니다.이것은 사용자의 IP를 취득하는 올바른 방법입니다.

 use Illuminate\Http\Request;

public function contactUS(Request $request)
    {
        echo $request->ip();
        return view('page.contactUS');
    }

그래도 127.0.0.1이 IP로 표시되는 경우는, 「프록시」를 추가할 필요가 있습니다만, 실가동하기 전에 변경할 필요가 있습니다.

"신뢰할 수 있는 프록시 구성"을 확인.

덧붙여 다음과 같이 합니다.

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies = '*';

지금이다request()->ip()는 올바른 IP를 제공합니다.

클라이언트 IP를 필요로 하고 서버가 aws elb 뒤에 있는 경우 다음 코드를 사용합니다.Larabel 5.3 테스트 완료

$elbSubnet = '172.31.0.0/16';
Request::setTrustedProxies([$elbSubnet]);
$clientIp = $request->ip();

해결책 1: 클라이언트 IP를 취득하기 위해 이 기능을 사용할 수 있습니다.

public function getClientIPaddress(Request $request) {
    $clientIp = $request->ip();
    return $clientIp;
}

해결책 2: 솔루션 1이 정확한 IP를 제공하지 않는 경우 이 기능을 사용하여 방문자의 실제 IP를 얻을 수 있습니다.

 public function getClientIPaddress(Request $request) {

    if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
        $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
        $_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
    }
    $client  = @$_SERVER['HTTP_CLIENT_IP'];
    $forward = @$_SERVER['HTTP_X_FORWARDED_FOR'];
    $remote  = $_SERVER['REMOTE_ADDR'];

    if(filter_var($client, FILTER_VALIDATE_IP)){
        $clientIp = $client;
    }
    elseif(filter_var($forward, FILTER_VALIDATE_IP)){
        $clientIp = $forward;
    }
    else{
        $clientIp = $remote;
    }

    return $clientIp;
 }

N.B: 라이브 서버에서 로드밸런서/프록시 서버를 사용한 경우 솔루션2를 사용하여 실제 방문자 IP를 취득해야 합니다.

이 솔루션은 제가 프로젝트에서 사용한 것입니다.다른 해법은 불완전하거나 너무 복잡해서 이해할 수 없다는 것을 알았습니다.

if (! function_exists('get_visitor_IP'))
{
    /**
     * Get the real IP address from visitors proxy. e.g. Cloudflare
     *
     * @return string IP
     */
    function get_visitor_IP()
    {
        // Get real visitor IP behind CloudFlare network
        if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
            $_SERVER['REMOTE_ADDR'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
            $_SERVER['HTTP_CLIENT_IP'] = $_SERVER["HTTP_CF_CONNECTING_IP"];
        }

        // Sometimes the `HTTP_CLIENT_IP` can be used by proxy servers
        $ip = @$_SERVER['HTTP_CLIENT_IP'];
        if (filter_var($ip, FILTER_VALIDATE_IP)) {
           return $ip;
        }

        // Sometimes the `HTTP_X_FORWARDED_FOR` can contain more than IPs 
        $forward_ips = @$_SERVER['HTTP_X_FORWARDED_FOR'];
        if ($forward_ips) {
            $all_ips = explode(',', $forward_ips);

            foreach ($all_ips as $ip) {
                if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)){
                    return $ip;
                }
            }
        }

        return $_SERVER['REMOTE_ADDR'];
    }
}

CDN + 로드 밸런서와 마찬가지로 여러 계층 프록시가 있는 경우.
Laravel Request::ip() 함수를 사용하면 오른쪽 끝에 있는 프록시 IP를 얻을 수 있지만 클라이언트 IP는 얻을 수 없습니다.
다음 해결책을 시도해 보십시오.

app/Http/Middleware/TrustProxies.php

protected $proxies = ['0.0.0.0/0'];

참고 자료: https://github.com/fideloper/TrustedProxy/issues/107#issuecomment-373065215

getIp 함수는 null을 반환하기 때문에 글로벌 요구에 따라 sebastien Horin 함수 getIp 및 request()->ip()를 사용했습니다.

$this->getIp() ?? request()->ip();

getIp 함수:

public function getIp(){
foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){
    if (array_key_exists($key, $_SERVER) === true){
        foreach (explode(',', $_SERVER[$key]) as $ip){
            $ip = trim($ip); // just to be safe
            if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){
                return $ip;
            }
        }
    }
}

}

IP 주소의 취득에 대해 염려하고 있습니다만, Larabel 기능이 필요 없거나, 사용하려고 하는 경우는, php만을 사용할 수 있습니다.

PHP < 5.3.0
$localIP = getHostByName(php_uname('n'));

PHP > = 5.3.0
$localIP = getHostByName(getHostName());

스레드에서 답한 대로: PHP 시스템의 로컬 IP를 얻는 방법

사용자의 데이터를 원할 때ip_address:

$_SERVER['REMOTE_ADDR']

서버 주소:

$_SERVER['SERVER_ADDR']
  $ip = $_SERVER['REMOTE_ADDR'];

언급URL : https://stackoverflow.com/questions/33268683/how-to-get-client-ip-address-in-laravel-5

반응형