11/08/2018, 20:54

Check nguồn truy cập dựa trên IP nhà mạng

Check nguồn truy cập dựa trên IP nhà mạng. Trong 1 số ứng dụng website cần detect người dùng truy cập từ mạng (di động) nào. Có nhiều cách để detect được. Thông thường nếu làm việc trực tiếp với nhà mạng thì chỉ cần lấy Params Header là xong. Nhưng vấn đề là không có thì thì có check được không? ...

Check nguồn truy cập dựa trên IP nhà mạng.

Trong 1 số ứng dụng website cần detect người dùng truy cập từ mạng (di động) nào. Có nhiều cách để detect được. Thông thường nếu làm việc trực tiếp với nhà mạng thì chỉ cần lấy Params Header là xong. Nhưng vấn đề là không có thì thì có check được không?

Câu trả lời là CÓ.

Vậy thì làm như thế nào?

Có 1 cách khá đơn giản là check dựa trên IP của nhà mạng, việc lấy IP của người dùng rất dễ rồi, lấy list IP của nhà mạng cũng dễ không kém.

OK, vậy triển như thế nào ?

Đầu tiên, cần lấy IP của người dùng.

Với PHP, việc lấy IP của người dùng vô cùng đơn giản rồi nhỉ :) Chúng ta có 1 đoạn code trông kiểu như thế này.

if (!function_exists('getIpAddress')) {
    function getIpAddress($convertToInteger = false)
    {
        $ip = ';
        if ($_SERVER) {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $ip = $_SERVER['HTTP_CLIENT_IP'];
            } else {
                $ip = $_SERVER['REMOTE_ADDR'];
            }
        } else {
            if (getenv('HTTP_X_FORWARDED_FOR')) {
                $ip = getenv('HTTP_X_FORWARDED_FOR');
            } elseif (getenv('HTTP_CLIENT_IP')) {
                $ip = getenv('HTTP_CLIENT_IP');
            } else {
                $ip = getenv('REMOTE_ADDR');
            }
        }
        // Convert IP string to Integer
        // Example, IP: 127.0.0.1 --> 2130706433
        if ($convertToInteger) {
            $ip = ip2long($ip);
        }
        return $ip;
    }
}

Khi sử dụng, chỉ việc gọi

$ip = getIpAddress();

-> Lấy được địa chỉ IP của người dùng.

Vậy còn IP của nhà mạng thì sao?

Vài câu lệnh với Google, ta có link sau: https://www.vnnic.vn/vnix/danh-b%E1%BA%A1-ipasn

Ở đây là list ra hầu hết các IP của nhà mạng Việt Nam rồi. Chỉ việc parse nó vào 1 Array là ngon nhỉ :D

VD: Mình có parse 1 array nhà mạng Viettel tại link này: https://github.com/nguyenanhung/Script-Check-3G-Viettel/blob/master/list_ip_range.php, các bạn có thể vào tham khảo :D

Sau khi có được 2 thứ trên, cần làm gì tiếp theo?

Vì hầu hết IP nhà mạng đang dừng ở IP v4, nên cần check IP của người dùng có phải là IP v4 hay không cái đã

if (!function_exists('checkIpV4')) {
    function checkIpV4($IpAddress)
    {
        if (!filter_var($IpAddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === FALSE) {
            return TRUE;
        } else {
            return FALSE;
        }
    }
}

Chốt hạ.

Sau khi check được IP của người dùng là IP v4, chỉ cần lấy ip của người dùng rồi in_array, nếu nó tồn tại trong mảng IP List đã khai báo của nhà mạng -> Return TRUE, ngược lại là FALSE thôi.

// Lấy địa chỉ IP kết nối hiện tại
$connect_ip  = getIpAddress();
// Check IP v4
$check_ip_v4 = checkIpV4($connect_ip);
// Kiểm tra tính hợp lệ của IP
if ($check_ip_v4 === TRUE) {
    // Tách mảng IP
    $ex_ip      = explode('.', $connect_ip);
    // List IP 2 index
    $ip_2_index = $ex_ip[0] . '.' . $ex_ip[1];
    // List IP 3 index
    $ip_3_index = $ex_ip[0] . '.' . $ex_ip[1] . '.' . $ex_ip[2];
    // Kiểm tra IP trong list
    if (in_array($ip_3_index, $list_ip_range_viettel)) {
        // list_ip_range_viettel là tên biến Array đã đề cập trong bước 2.
        // Có tồn tại IP 3 index
        $is_3g_viettel = TRUE;
    } else {
        if (in_array($ip_2_index, $list_ip_range_viettel)) {
            // Có tồn tại IP 2 index
            $is_3g_viettel = TRUE;
        } else {
            // Ko thỏa mãn cả 2 điều kiện, Return False
            $is_3g_viettel = FALSE;
        }
    }
} else {
    // Return FALSE
    $is_3g_viettel = FALSE;
}
// Test
echo "<pre>";
print_r($is_3g_viettel);
echo "</pre>";

Done :)

Ngoài ra thì đây là hàng full không che: https://github.com/nguyenanhung/Script-Check-3G-Viettel

NguyenAnHung 13-07-2016

0