2012-04-28 60 views
11

Tôi tò mò nếu có bất kỳ thư viện nào xử lý loại nội dung này hoặc tôi phải tự mình làm điều đó một lần nữa. Vì vậy, điều tôi muốn nhận được trường địa chỉ IP từ yêu cầu tiêu đề HTTP của khách truy cập trên máy chủ của tôi và làm toàn bộ điều trong Java? Mọi sự giúp đỡ đều là tốt. Cảm ơn trước.Làm cách nào tôi có thể lấy địa chỉ IP từ tiêu đề HTTP trong Java

Trả lời

28

Sử dụng phương pháp getHeader(String Name) đối tượng javax.servlet.http.HttpServletRequest để truy lục giá trị của biến số Remote_Addr. Đây là đoạn mã mẫu:

String ipAddress = request.getHeader("Remote_Addr"); 

Nếu mã này trả về chuỗi rỗng, sau đó sử dụng theo cách này:

String ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR"); 

if (ipAddress == null) { 
    ipAddress = request.getRemoteAddr(); 
} 
+1

Đó là tuyệt vời! :) Cảm ơn bạn, có phương pháp nào dựa trên địa chỉ IP đã cho có thể kết luận từ quốc gia nào là khách truy cập không? P.S. Sẽ đánh dấu nó là tốt nhất, bởi vì bạn đã trả lời trên của tôi Q. –

+1

Để nhận ra quốc gia/thành phố sử dụng dịch vụ GeoIP. Ví dụ: kiểm tra liên kết này: http://www.maxmind.com/app/java –

+2

Geocode địa chỉ IP: http://stackoverflow.com/questions/3232516/geocode-an-ip-address –

7

Mặc dù có một câu trả lời chấp nhận rằng đã bỏ phiếu tán cao Tôi muốn đề nghị một thay thế và chỉ ra những thiếu sót của câu trả lời được chấp nhận.

request.getHeader("Remote_Addr")specified để trả lại chính xác giống như request.getRemoteAddr(). Do đó, nó không có ý nghĩa để kiểm tra cả hai. Cũng lưu ý rằng getRemoteAddr là một phương thức javax.servlet.ServletRequest (tức là HTTP-thuyết bất khả tri) trong khi getHeader nằm trong javax.servlet.http.HttpServletRequest.

Hơn nữa, một số proxy sử dụng Client-IP thay vì X-Forwarded-For. Để thảo luận, hãy xem https://stackoverflow.com/a/7446010/131929.

Tôi không biết cách sử dụng HTTP_X_FORWARDED_FOR đáng tin cậy trên X-Forwarded-For là như thế nào. Trong Java tôi muốn sử dụng trực tiếp, hình thức ngắn. Để thảo luận, hãy xem https://stackoverflow.com/a/3834169/131929. Trường hợp trên/dưới không có sự khác biệt bởi vì getHeaderspecified là trường hợp trong số nhạy cảm.

Java thay thế

public final class ClientIpAddress { 

    // CHECKSTYLE:OFF 
    // https://stackoverflow.com/a/11327345/131929 
    private static Pattern PRIVATE_ADDRESS_PATTERN = Pattern.compile(
     "(^127\\.)|(^192\\.168\\.)|(^10\\.)|(^172\\.1[6-9]\\.)|(^172\\.2[0-9]\\.)|(^172\\.3[0-1]\\.)|(^::1$)|(^[fF][cCdD])", 
     Pattern.CANON_EQ); 
    // CHECKSTYLE:ON 

    private ClientIpAddress() { 
    } 

    /** 
    * Extracts the "real" client IP address from the request. It analyzes request headers 
    * {@code REMOTE_ADDR}, {@code X-Forwarded-For} as well as {@code Client-IP}. Optionally 
    * private/local addresses can be filtered in which case an empty string is returned. 
    * 
    * @param request HTTP request 
    * @param filterPrivateAddresses true if private/local addresses (see 
    * https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces and 
    * https://en.wikipedia.org/wiki/Unique_local_address) should be filtered i.e. omitted 
    * @return IP address or empty string 
    */ 
    public static String getFrom(HttpServletRequest request, boolean filterPrivateAddresses) { 
    String ip = request.getRemoteAddr(); 

    String headerClientIp = request.getHeader("Client-IP"); 
    String headerXForwardedFor = request.getHeader("X-Forwarded-For"); 
    if (StringUtils.isEmpty(ip) && StringUtils.isNotEmpty(headerClientIp)) { 
     ip = headerClientIp; 
    } else if (StringUtils.isNotEmpty(headerXForwardedFor)) { 
     ip = headerXForwardedFor; 
    } 
    if (filterPrivateAddresses && isPrivateOrLocalAddress(ip)) { 
     return StringUtils.EMPTY; 
    } else { 
     return ip; 
    } 
    } 

    private static boolean isPrivateOrLocalAddress(String address) { 
    Matcher regexMatcher = PRIVATE_ADDRESS_PATTERN.matcher(address); 
    return regexMatcher.matches(); 
    } 
} 

PHP thay thế

function getIp() 
{ 
    $ip = $_SERVER['REMOTE_ADDR']; 

    if (empty($ip) && !empty($_SERVER['HTTP_CLIENT_IP'])) { 
     $ip = $_SERVER['HTTP_CLIENT_IP']; 
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
     // omit private IP addresses which a proxy forwarded 
     $tmpIp = $_SERVER['HTTP_X_FORWARDED_FOR']; 
     $tmpIp = filter_var(
      $tmpIp, 
      FILTER_VALIDATE_IP, 
      FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE 
     ); 
     if ($tmpIp != false) { 
      $ip = $tmpIp; 
     } 
    } 
    return $ip; 
} 
+0

Giải pháp của bạn thật thanh lịch và tôi sử dụng nó. UpVote – Mubasher

+0

X-Forwarded-For có thể chứa danh sách các địa chỉ IP proxy được phân cách bằng dấu phẩy, vì vậy tôi sẽ chia chuỗi trước tiên. –

Các vấn đề liên quan