[php] Laravel 5 이상에서 클라이언트 IP 주소를 얻는 방법

Laravel에서 클라이언트의 IP 주소를 얻으려고합니다.

를 사용하여 PHP로 클라이언트의 IP를 쉽게 얻을 수 $_SERVER["REMOTE_ADDR"]있습니다. 핵심 PHP에서는 제대로 작동하지만 Laravel에서 동일한 것을 사용하면 방문자의 IP 대신 서버 IP를 반환합니다.



답변

Laravel API 살펴보기 :

Request::ip();

내부적으로 Symfony Request ObjectgetClientIps메소드를 사용합니다 .

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은 \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;
                }
            }
        }
    }
}

이 외에도 Laravel의 스로틀 미들웨어를 사용하는 데 매우주의해야 합니다. Laravel도 사용 Request::ip()하므로 모든 방문자가 동일한 사용자로 식별되며 스로틀 한계에 매우 빨리 도달합니다. 나는이 라이브를 경험했고 이것은 큰 문제를 일으켰습니다.

이 문제를 해결하려면

Illuminate \ Http \ Request.php

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

이제 Request::ip()프로덕션에서 실제 IP를 반환해야하는을 사용할 수도 있습니다 .


답변

사용하십시오 request()->ip().

내가 이해 한 바에 따르면, Laravel 5부터 다음과 같은 전역 기능을 사용하는 것이 좋습니다.

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

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


답변

네임 스페이스 추가

use Request;

그런 다음 함수를 호출하십시오.

Request::ip();


답변

Laravel 5의 경우 Request 객체를 사용할 수 있습니다. ip()다음과 같은 메소드를 호출하십시오 .

$request->ip();


답변

라 라벨에서 5

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


답변

처리해야 할 두 가지가 있습니다.

  1. a를 반환 Illuminate\Http\Request하고 ->ip()메서드를 호출 하는 도우미 함수를 가져옵니다 .

    request()->ip();
  2. 서버 구성을 생각해보십시오. 프록시를 사용하거나 load-balancer특히 AWS ELB 구성을 사용할 수 있습니다 .

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

왜? 서버가 프록시 / load-balancerIP를 대신 가져 오기 때문 입니다.

AWS 밸런스 로더를 사용중인 경우 다음과 같이 선언을 App\Http\Middleware\TrustProxies작성 $proxies하십시오.

protected $proxies = '*';

이제 스로틀 미들웨어에 문제가 발생하지 않았으므로 테스트하고 축하하십시오. 또한 request()->ip()“TrustProxies”를 설정하거나 설정하지 않아도 범인의 IP 만 차단하는 대신 모든 사용자의 로그인을 차단할 수 있습니다.

또한 스로틀 미들웨어에 대한 설명이 문서에 제대로 설명되어 있지 않으므로 ” 초보자를위한 laravel 5.2 튜토리얼, API 속도 제한

Laravel 5.7에서 테스트