2013-08-21 46 views
18

Tôi tìm một số cách khác nhau để nhận ip trong servlet là gì. nhưng tôi không biết cái nào là đúng và tại sao.cách thích hợp để nhận yêu cầu ip

1:

request.getHeader("X-Real-IP") 

2:

String ip = request.getHeader("X-Forwarded-For"); 
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
     ip = request.getHeader("Proxy-Client-IP"); 
    } 
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
     ip = request.getHeader("WL-Proxy-Client-IP"); 
    } 
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
     ip = request.getHeader("HTTP_CLIENT_IP"); 
    } 
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
     ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 
    } 
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
     ip = request.getRemoteAddr(); 
    } ` 

3:

String ip=request.getHeader("x-forwarded-for"); 
       if(ip==null){ 
        ip=request.getRemoteAddr(); 
       } 
       String ips[]=ip.split(",");` 
           ip=ips[0]; 
+0

Kiểm tra liên kết này: http://stackoverflow.com/questions/10363069/how-can-i-retrieve-ip-address-from-http-header-in-java/10363109#10363109 –

Trả lời

43

Câu trả lời rất phức tạp.

  • Nếu servlet của bạn đang chạy trên một máy chủ web đó là đằng sau một reverse proxy hoặc cân bằng tải, sau đó proxy web có thể được cấu hình để tiêm một tiêu đề yêu cầu cung cấp cho các địa chỉ IP mà các yêu cầu đến từ đâu. Các proxy ngược khác nhau sẽ chèn các tiêu đề khác nhau. Tham khảo tài liệu cho máy chủ (front-end) của bạn.

  • Nếu khách hàng của bạn sử dụng proxy (chuyển tiếp), thì có thể chèn tiêu đề để nói địa chỉ IP của khách hàng là gì ... hoặc có thể không. Và địa chỉ IP chèn có thể không chính xác.

  • Giá trị bạn nhận được bằng cách gọi request.getRemoteAddr() sẽ là địa chỉ IP của yêu cầu ngay lập tức ngược dòng của yêu cầu.

Không có tiêu đề nào bạn liệt kê là tiêu chuẩn, nhưng "x được chuyển tiếp" được coi là tiêu chuẩn defacto; tức là nó là loại có nhiều khả năng được chèn vào bởi một proxy, vv ... nếu bất cứ thứ gì được tiêm vào.

Cuối cùng, ngay cả khi bạn đã nhận được một địa chỉ IP, nó sẽ không nhất thiết giúp bạn. Ví dụ, nếu khách hàng ngồi trên một mạng riêng và kết nối với internet thông qua một cổng NAT, thì địa chỉ IP trong yêu cầu HTTP sẽ là một địa chỉ của máy chủ NAT ... không phải là IP khách hàng thực tế.


Vậy điều này có nghĩa là gì? Về cơ bản, điều đó có nghĩa là nói chung là bạn không thể đáng tin cậy tìm địa chỉ IP của hệ thống mà yêu cầu bắt nguồn từ đó.

+0

cảm ơn bạn đã trả lời tuyệt vời, chúng tôi sử dụng nginx + tomcat + spring + spring mvc + mybatis, tôi đang ở Trung Quốc, đây là câu hỏi thứ hai của tôi về stackoverflow, lần đầu tiên tôi thất bại-- !. tôi nghĩ rằng chúng ta nên làm nhiều thử nghiệm hơn về nó. – sprite

+0

@sprite - bạn nên kiểm tra tài liệu nginx để tìm ra tiêu đề đang sử dụng. Nhưng điều đó sẽ chỉ cung cấp cho bạn địa chỉ IP của máy chủ lưu trữ ngược dòng tiếp theo ... có thể không phải là khách hàng thực sự. Như tôi đã nói, bạn không thể luôn luôn có được IP khách hàng thực sự ... và thậm chí nếu bạn có thể, nó sẽ không nhất thiết là đáng tin cậy, hữu ích hay độc đáo. –

+0

ok, tôi gần như đã hiểu lời khuyên của bạn. 'Địa chỉ IP của máy chủ lưu trữ ngược dòng tiếp theo' có phải là địa chỉ IP của proxy cuối cùng không? @Stephen C – sprite

8

này dường như hầu hết chúng ta có thể làm để có được địa chỉ IP gốc của khách hàng

String ipAddress = request.getHeader("X-FORWARDED-FOR"); 
if (ipAddress == null) { 
    ipAddress = request.getRemoteAddr(); 
} 
+0

thankyou rất nhiều – sprite

+5

Ngoại trừ khi nó không; xem Câu trả lời của tôi. –

+7

Điều này sẽ không hoạt động vì X-Forwarded-For có thể chứa danh sách địa chỉ IP proxy được tùy chọn bằng dấu phẩy (tùy chọn với khoảng trắng)! – Yeti