IT

Laravel 5+에서 클라이언트 IP 주소를 얻는 방법은 무엇입니까?

lottoking 2020. 8. 4. 22:48
반응형

Laravel 5+에서 클라이언트 IP 주소를 얻는 방법은 무엇입니까?


Laravel에서 클라이언트의 IP 주소를 얻으려고합니다. 우리 모두 알고 있는지를 사용하여 PHP로 클라이언트의 IP를 얻는 것이 무엇인지 알고 $_SERVER["REMOTE_ADDR"]있습니다.

핵심 PHP에서는 작동하지만 Laravel에서 동일한 것을 사용하면 방문자 IP 대신 서버 IP를 제공합니다.


라 라벨 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);
} 

사용하다 request()->ip()

Laravel 5부터 (내가 이해 한 것에서) 다음과 같은 전역 함수를 사용하는 것이 좋습니다 / 좋은 습관입니다.

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

당신은 요점을 얻는다 :-) 그리고 무엇이든, 정적 정적 대신 함수를 사용할 때 내 IDE는 크리스마스 트리처럼 들리지 않는다. ;-)


부하 분산 장치를 사용하는 경우

라 라벨은 \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의 스로틀 미들웨어를 사용하는 데 매우주의 할 것을 제안합니다. Laravel도 사용 Request::ip()하므로 모든 방문자가 동일한 사용자로 식별되고 스로틀 제한에 매우 빠르게 도달하게됩니다. 라이브 경험 ... 이로 인해 큰 문제가 발생했습니다 ...

이 문제를 해결하려면 :

Illuminate \ Http \ Request.php

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

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


네임 스페이스 추가

use Request;

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

Request::ip();

Laravel 5의 경우 Request 객체를 사용할 수 있습니다. ip () 메서드를 호출하면됩니다. 다음과 같은 것 :

$request->ip();


Laravel 5에서

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

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

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

request()->ip();

2) 서버 구성을 생각하십시오. proxy또는 load balancer(특히 AWS ELB구성에서) 사용할 수 있습니다.

이 경우 신뢰할 수있는 프록시구성 하거나 Trusting All Proxies옵션을 설정해야합니다 .

왜?

서버가되는 것은 대신 프록시 / 밸런스 로더 IP를 가져 오기 때문입니다.

어떻게?

당신이 아니라면 AWS balance-loader

이동 App\Http\Middleware\TrustProxies

와 메이크업의 $proxies이 같은 선언보기 :

protected $proxies = '*';

이제 테스트하고 축하하십시오 throttle middleware.. 또한 request()->ip()설정 에 의존 하거나 설정하지 않고 TrustProxies범인의 IP 만 차단하는 대신 모든 사용자의 로그인을 차단할 수 있습니다.

그리고 throttle middleware문서에 제대로 설명되어 있지 않기 때문에이 비디오를 시청 하는 것이 좋습니다.

Laravel 5.7에서 테스트 됨


버전 laravel 5.4에서는 ip 사용자를 얻는 올바른 방법으로 ip static을 호출 할 수 없습니다.

 use Illuminate\Http\Request;

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

여전히 IP로 127.0.0.1을 받고 있다면 "프록시"를 추가해야합니다.

그러나 생산을 시작하기 전에 변경해야합니다.

이 부분을 읽으십시오 : https://laravel.com/docs/5.7/requests#configuring-trusted-proxies

이제 다음을 추가하십시오.

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

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


클라이언트 IP를 원하고 서버가 aws elb 뒤에있는 경우 다음 코드를 사용합니다. laravel 5.3 용으로 테스트 됨

$elbSubnet = '172.31.0.0/16';
Request::setTrustedProxies([$elbSubnet]);
$clientIp = $request->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;
    }

사용자가 원하는 경우 ip_address:

$_SERVER['REMOTE_ADDR']

서버 주소를 원합니다.

$_SERVER['SERVER_ADDR']

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

반응형