Hướng dẫn dùng _server remote_addr trong PHP

Nhiều khi chúng ta cần lấy địa chỉ IP của người truy cập cho các mục đích khác nhau như bảo mật, huyển hướng khách truy cập đến trang khác, chặn / cấm khách truy cập....

Vậy để thu thập được địa chỉ IP của người dùng một cách dễ dàng trong PHP bằng biến $_SERVER

Cách đơn giản nhất để lấy địa chỉ IP của khách truy cập hiện tại trong PHP là sử dụng REMOTE_ADDR trong biến $_SERVER có sẵn trong PHP. 

Lấy địa chỉ IP của client

$_SERVER ['REMOTE_ADDR'] - Nó trả về địa chỉ IP của người dùng hiện đang truy cập trang web.

Ví dụ: 

  

Kết quả :

User IP Address - ::1

Nhưng đôi khi REMOTE_ADDR không trả về địa chỉ IP của máy khách và lý do chính đằng sau là sử dụng proxy. Trong tình huống như vậy, chúng tôi sẽ thử một cách khác để lấy địa chỉ IP thực của người dùng trong PHP.

  

Sơ đồ lấy chương trình lấy địa chỉ IP

Sơ đồ cho chương trình trên sẽ giống như dưới đây.

Lấy địa chỉ IP của website

Một cách khác để lấy địa chỉ IP của bất kỳ trang web nào bằng URL của nó bằng gethostbyname[].

Ví dụ:

  

Kết quả: 

IP Address of Google is - 172.217.166.4
IP Address of javaTpoint is - 95.216.57.234

$ _SERVER là một biến toàn cục của PHP chứa thông tin về tiêu đề, đường dẫn và vị trí tập lệnh.

$_SERVER['SERVER_ADDR']  Returns IP address của host

$_SERVER['SERVER_NAME']  Returns Hostname Server

Chúc các bạn thành công.

answer

1230

Dù bạn làm gì, hãy đảm bảo không tin tưởng dữ liệu được gửi từ khách hàng. $_SERVER['REMOTE_ADDR']chứa địa chỉ IP thực của bên kết nối. Đó là giá trị đáng tin cậy nhất mà bạn có thể tìm thấy.

Tuy nhiên, họ có thể đứng sau một máy chủ proxy trong trường hợp proxy có thể đã đặt $_SERVER['HTTP_X_FORWARDED_FOR'], nhưng giá trị này dễ bị giả mạo. Ví dụ: nó có thể được đặt bởi một người không có proxy hoặc IP có thể là IP bên trong từ mạng LAN phía sau proxy.

Điều này có nghĩa là nếu bạn sẽ lưu $_SERVER['HTTP_X_FORWARDED_FOR'], hãy chắc chắn rằng bạn cũng lưu $_SERVER['REMOTE_ADDR']giá trị. Ví dụ: bằng cách lưu cả hai giá trị trong các trường khác nhau trong cơ sở dữ liệu của bạn.

Nếu bạn định lưu IP vào cơ sở dữ liệu dưới dạng chuỗi, hãy đảm bảo bạn có không gian cho ít nhất 45 ký tự . IPv6 vẫn ở đây và những địa chỉ đó lớn hơn địa chỉ IPv4 cũ.

[Lưu ý rằng IPv6 thường sử dụng tối đa 39 ký tự nhưng cũng có ký hiệu IPv6 đặc biệt cho các địa chỉ IPv4 mà ở dạng đầy đủ có thể lên tới 45 ký tự. Vì vậy, nếu bạn biết bạn đang làm gì, bạn có thể sử dụng 39 ký tự, nhưng nếu bạn chỉ muốn thiết lập và quên nó, sử dụng 45].

1230 hữu ích 5 bình luận chia sẻ

answer

403

$_SERVER['REMOTE_ADDR']có thể không thực sự chứa địa chỉ IP của máy khách thực sự, vì nó sẽ cung cấp cho bạn một địa chỉ proxy cho các máy khách được kết nối thông qua proxy chẳng hạn. Tuy nhiên, đó cũng có thể là những gì bạn thực sự muốn, tùy thuộc vào những gì bạn làm với IP. Địa chỉ RFC1918 riêng tư của ai đó có thể không giúp ích gì cho bạn nếu bạn nói, cố gắng xem lưu lượng truy cập của bạn đến từ đâu hoặc nhớ IP mà người dùng kết nối lần cuối từ đâu, nơi IP công cộng của proxy hoặc cổng NAT có thể nhiều hơn thích hợp để lưu trữ.

Có một số tiêu đề HTTP giống như X-Forwarded-Forcó thể được đặt bởi các proxy khác nhau. Vấn đề là đó chỉ là những tiêu đề HTTP có thể được đặt bởi bất kỳ ai. Không có gì đảm bảo về nội dung của họ. $_SERVER['REMOTE_ADDR']là địa chỉ IP vật lý thực tế mà máy chủ web nhận được kết nối từ đó và phản hồi sẽ được gửi đến. Bất cứ điều gì khác chỉ là thông tin tùy ý và tự nguyện. Chỉ có một kịch bản mà bạn có thể tin tưởng vào thông tin này: bạn đang kiểm soát proxy đặt tiêu đề này. Chỉ có nghĩa là nếu bạn biết 100% tiêu đề được đặt ở đâu và như thế nào thì bạn nên chú ý đến nó cho bất cứ điều gì quan trọng.

Phải nói rằng, đây là một số mã mẫu:

if [!empty[$_SERVER['HTTP_CLIENT_IP']]] {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif [!empty[$_SERVER['HTTP_X_FORWARDED_FOR']]] {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

Lưu ý của biên tập viên: Sử dụng đoạn mã trên có ý nghĩa bảo mật . Máy khách có thể đặt tất cả thông tin tiêu đề HTTP [nghĩa là $_SERVER['HTTP_...] thành bất kỳ giá trị tùy ý nào nó muốn. Vì vậy, nó đáng tin cậy hơn để sử dụng $_SERVER['REMOTE_ADDR'], vì người dùng không thể cài đặt cái này.

Từ: //roshanbh.com.np/2007/12/getting-real-ip-address-in-php.html

403 hữu ích 5 bình luận chia sẻ

answer

193

193 hữu ích 5 bình luận chia sẻ

answer

105

Dưới đây là một mẫu mã sạch hơn về một cách tốt để lấy địa chỉ IP của người dùng.

$ip = $_SERVER['HTTP_CLIENT_IP'] ? $_SERVER['HTTP_CLIENT_IP'] : [$_SERVER['HTTP_X_FORWARDED_FOR'] ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']];

Đây là phiên bản ngắn hơn sử dụng toán tử elvis:

$_SERVER['HTTP_CLIENT_IP'] ? : [$_SERVER['HTTP_X_FORWARDED_FOR'] ? : $_SERVER['REMOTE_ADDR']];

Đây là phiên bản sử dụng isset để xóa thông báo [cảm ơn bạn, @shasi kanth]:

$ip = isset[$_SERVER['HTTP_CLIENT_IP']] ? $_SERVER['HTTP_CLIENT_IP'] : isset[$_SERVER['HTTP_X_FORWARDED_FOR']] ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];

105 hữu ích 5 bình luận chia sẻ

answer

86

Nó nên được chứa trong $_SERVER['REMOTE_ADDR']biến.

86 hữu ích 0 bình luận chia sẻ

answer

50

Giải pháp yêu thích của tôi là cách Zend Framework 2 sử dụng. Nó cũng xem xét $_SERVERtính chất HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP, REMOTE_ADDRnhưng nó khai báo một lớp cho nó để thiết lập một số proxy tin cậy và nó sẽ trả về một địa chỉ IP không phải là một mảng. Tôi nghĩ rằng đây là giải pháp gần nhất với nó:

class RemoteAddress
{
    /**
     * Whether to use proxy addresses or not.
     *
     * As default this setting is disabled - IP address is mostly needed to increase
     * security. HTTP_* are not reliable since can easily be spoofed. It can be enabled
     * just for more flexibility, but if user uses proxy to connect to trusted services
     * it's his/her own risk, only reliable field for IP address is $_SERVER['REMOTE_ADDR'].
     *
     * @var bool
     */
    protected $useProxy = false;

    /**
     * List of trusted proxy IP addresses
     *
     * @var array
     */
    protected $trustedProxies = array[];

    /**
     * HTTP header to introspect for proxies
     *
     * @var string
     */
    protected $proxyHeader = 'HTTP_X_FORWARDED_FOR';

    // [...]

    /**
     * Returns client IP address.
     *
     * @return string IP address.
     */
    public function getIpAddress[]
    {
        $ip = $this->getIpAddressFromProxy[];
        if [$ip] {
            return $ip;
        }

        // direct IP address
        if [isset[$_SERVER['REMOTE_ADDR']]] {
            return $_SERVER['REMOTE_ADDR'];
        }

        return '';
    }

    /**
     * Attempt to get the IP address for a proxied client
     *
     * @see //tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10#section-5.2
     * @return false|string
     */
    protected function getIpAddressFromProxy[]
    {
        if [!$this->useProxy
            || [isset[$_SERVER['REMOTE_ADDR']] && !in_array[$_SERVER['REMOTE_ADDR'], $this->trustedProxies]]
        ] {
            return false;
        }

        $header = $this->proxyHeader;
        if [!isset[$_SERVER[$header]] || empty[$_SERVER[$header]]] {
            return false;
        }

        // Extract IPs
        $ips = explode[',', $_SERVER[$header]];
        // trim, so we can compare against trusted proxies properly
        $ips = array_map['trim', $ips];
        // remove trusted proxy IPs
        $ips = array_diff[$ips, $this->trustedProxies];

        // Any left?
        if [empty[$ips]] {
            return false;
        }

        // Since we've removed any known, trusted proxy servers, the right-most
        // address represents the first IP we do not know about -- i.e., we do
        // not know if it is a proxy server, or a client. As such, we treat it
        // as the originating IP.
        // @see //en.wikipedia.org/wiki/X-Forwarded-For
        $ip = array_pop[$ips];
        return $ip;
    }

    // [...]
}

Xem mã đầy đủ tại đây: //raw.githubusercontent.com/zendframework/zend-http/master/src/PhpEnFE/RemoteAddress.php

50 hữu ích 5 bình luận chia sẻ

answer

42

Có nhiều loại người dùng khác nhau đằng sau Internet, vì vậy chúng tôi muốn bắt địa chỉ IP từ các phần khác nhau. Những người đang có:

1.$_SERVER['REMOTE_ADDR'] - Điều này chứa địa chỉ IP thực của khách hàng. Đó là giá trị đáng tin cậy nhất mà bạn có thể tìm thấy từ người dùng.

2.$_SERVER['REMOTE_HOST'] - Điều này sẽ lấy tên máy chủ mà người dùng đang xem trang hiện tại. Nhưng để tập lệnh này hoạt động, phải tìm kiếm tên máy chủ lưu trữ bên trong httpd.conf.

3.$_SERVER['HTTP_CLIENT_IP'] - Điều này sẽ lấy địa chỉ IP khi người dùng đến từ các dịch vụ Internet được chia sẻ.

4.$_SERVER['HTTP_X_FORWARDED_FOR'] - Điều này sẽ lấy địa chỉ IP từ người dùng khi anh ấy / cô ấy đứng sau proxy.

Vì vậy, chúng ta có thể sử dụng chức năng kết hợp sau đây để lấy địa chỉ IP thực từ những người dùng đang xem ở các vị trí khác nhau,

// Function to get the user IP address
function getUserIP[] {
    $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_X_CLUSTER_CLIENT_IP']]]
        $ipaddress = $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    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;
}

42 hữu ích 1 bình luận chia sẻ

answer

30

Sau đây là phương pháp tiên tiến nhất mà tôi đã tìm thấy và tôi đã thử một số phương pháp khác trong quá khứ. Nó là hợp lệ để đảm bảo có được địa chỉ IP của khách truy cập [nhưng xin lưu ý rằng bất kỳ hacker nào cũng có thể làm sai lệch địa chỉ IP một cách dễ dàng].

function get_ip_address[] {

    // Check for shared Internet/ISP IP
    if [!empty[$_SERVER['HTTP_CLIENT_IP']] && validate_ip[$_SERVER['HTTP_CLIENT_IP']]] {
        return $_SERVER['HTTP_CLIENT_IP'];
    }

    // Check for IP addresses passing through proxies
    if [!empty[$_SERVER['HTTP_X_FORWARDED_FOR']]] {

        // Check if multiple IP addresses exist in var
        if [strpos[$_SERVER['HTTP_X_FORWARDED_FOR'], ','] !== false] {
            $iplist = explode[',', $_SERVER['HTTP_X_FORWARDED_FOR']];
            foreach [$iplist as $ip] {
                if [validate_ip[$ip]]
                    return $ip;
            }
        }
        else {
            if [validate_ip[$_SERVER['HTTP_X_FORWARDED_FOR']]]
                return $_SERVER['HTTP_X_FORWARDED_FOR'];
        }
    }
    if [!empty[$_SERVER['HTTP_X_FORWARDED']] && validate_ip[$_SERVER['HTTP_X_FORWARDED']]]
        return $_SERVER['HTTP_X_FORWARDED'];
    if [!empty[$_SERVER['HTTP_X_CLUSTER_CLIENT_IP']] && validate_ip[$_SERVER['HTTP_X_CLUSTER_CLIENT_IP']]]
        return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    if [!empty[$_SERVER['HTTP_FORWARDED_FOR']] && validate_ip[$_SERVER['HTTP_FORWARDED_FOR']]]
        return $_SERVER['HTTP_FORWARDED_FOR'];
    if [!empty[$_SERVER['HTTP_FORWARDED']] && validate_ip[$_SERVER['HTTP_FORWARDED']]]
        return $_SERVER['HTTP_FORWARDED'];

    // Return unreliable IP address since all else failed
    return $_SERVER['REMOTE_ADDR'];
}

/**
 * Ensures an IP address is both a valid IP address and does not fall within
 * a private network range.
 */
function validate_ip[$ip] {

    if [strtolower[$ip] === 'unknown']
        return false;

    // Generate IPv4 network address
    $ip = ip2long[$ip];

    // If the IP address is set and not equivalent to 255.255.255.255
    if [$ip !== false && $ip !== -1] {
        // Make sure to get unsigned long representation of IP address
        // due to discrepancies between 32 and 64 bit OSes and
        // signed numbers [ints default to signed in PHP]
        $ip = sprintf['%u', $ip];

        // Do private network range checking
        if [$ip >= 0 && $ip = 167772160 && $ip = 2130706432 && $ip = 2851995648 && $ip = 2886729728 && $ip = 3221225984 && $ip = 3232235520 && $ip = 4294967040]
            return false;
    }
    return true;
}

30 hữu ích 3 bình luận chia sẻ

answer

27

Câu trả lời là sử dụng $_SERVERbiến. Ví dụ, $_SERVER["REMOTE_ADDR"]sẽ trả về địa chỉ IP của khách hàng.

27 hữu ích 0 bình luận chia sẻ

answer

10

Như tất cả những người khác đã nói trước khi bạn có thể sử dụng $_SERVER['REMOTE_ADDR'];để lấy địa chỉ IP của khách hàng.

Ngoài ra, nếu bạn cần thêm thông tin về người dùng, bạn có thể sử dụng điều này:

Chủ Đề