Laravel에서 클라이언트의 IP 주소를 얻으려고합니다.
를 사용하여 PHP로 클라이언트의 IP를 쉽게 얻을 수 $_SERVER["REMOTE_ADDR"]
있습니다. 핵심 PHP에서는 제대로 작동하지만 Laravel에서 동일한 것을 사용하면 방문자의 IP 대신 서버 IP를 반환합니다.
답변
Laravel API 살펴보기 :
Request::ip();
내부적으로 Symfony Request Object 의 getClientIps
메소드를 사용합니다 .
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();
}
답변
처리해야 할 두 가지가 있습니다.
-
a를 반환
Illuminate\Http\Request
하고->ip()
메서드를 호출 하는 도우미 함수를 가져옵니다 .request()->ip();
-
서버 구성을 생각해보십시오. 프록시를 사용하거나
load-balancer
특히 AWS ELB 구성을 사용할 수 있습니다 .
이 경우 ” 신뢰할 수있는 프록시 구성 “을 따르 거나 “모든 프록시 신뢰”옵션을 설정해야합니다.
왜? 서버가 프록시 / load-balancer
IP를 대신 가져 오기 때문 입니다.
AWS 밸런스 로더를 사용중인 경우 다음과 같이 선언을 App\Http\Middleware\TrustProxies
작성 $proxies
하십시오.
protected $proxies = '*';
이제 스로틀 미들웨어에 문제가 발생하지 않았으므로 테스트하고 축하하십시오. 또한 request()->ip()
“TrustProxies”를 설정하거나 설정하지 않아도 범인의 IP 만 차단하는 대신 모든 사용자의 로그인을 차단할 수 있습니다.
또한 스로틀 미들웨어에 대한 설명이 문서에 제대로 설명되어 있지 않으므로 ” 초보자를위한 laravel 5.2 튜토리얼, API 속도 제한 “
Laravel 5.7에서 테스트