2013-04-23 18 views
29

Mam problem z prostym problemem. Uzyskałbym adres IP klienta rzeczywistego w urządzeniu HTTPServlet.Uzyskaj prawdziwy adres IP klienta w serwecie

Od teraz użyłem:

request.getRemoteAddr() 

Teraz jednak wraca fałszywe IP. np .: xxx.xxx.xxx. ale mój adres IP jest podobny do xxx.xxx.xxx. . (sprawdzone na http://whatismyipaddress.com/).

Teraz starałem się używać:

request.getHeader("X-Forwarded-For") 

Zwraca NULL.

Wziąłem również sondę z następujących klas:

public class IpUtils { 

public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; 
public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$"); 

public static String longToIpV4(long longIp) { 
    int octet3 = (int) ((longIp >> 24) % 256); 
    int octet2 = (int) ((longIp >> 16) % 256); 
    int octet1 = (int) ((longIp >> 8) % 256); 
    int octet0 = (int) ((longIp) % 256); 

    return octet3 + "." + octet2 + "." + octet1 + "." + octet0; 
} 

public static long ipV4ToLong(String ip) { 
    String[] octets = ip.split("\\."); 
    return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16) 
      + (Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]); 
} 

public static boolean isIPv4Private(String ip) { 
    long longIp = ipV4ToLong(ip); 
    return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255")) 
      || (longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255")) 
      || longIp >= ipV4ToLong("192.168.0.0") && longIp <= ipV4ToLong("192.168.255.255"); 
} 

public static boolean isIPv4Valid(String ip) { 
    return pattern.matcher(ip).matches(); 
} 

public static String getIpFromRequest(HttpServletRequest request) { 
    String ip; 
    boolean found = false; 
    if ((ip = request.getHeader("x-forwarded-for")) != null) { 
     StringTokenizer tokenizer = new StringTokenizer(ip, ","); 
     while (tokenizer.hasMoreTokens()) { 
      ip = tokenizer.nextToken().trim(); 
      if (isIPv4Valid(ip) && !isIPv4Private(ip)) { 
       found = true; 
       break; 
      } 
     } 
    } 

    if (!found) { 
     ip = request.getRemoteAddr(); 
    } 

    return ip; 
} 
} 

powrócił on również xxx.xxx.xxx.50 IP. :(

Teraz nie wiem jak uzyskać prawdziwe IP klienta. Jeśli ktoś zna rozwiązanie prosimy o odpowiedź.

+0

Czy Twój serwer bezpośrednio podłączony do Internetu? Czy są jakieś routery, load balancery, urządzenia NAT itp.? – mindas

+0

Jest tylko ruter. – TAR515

Odpowiedz

27

Przypuszczam, że Twoim problemem jest to, że używasz serwera gdzieś w sieci lokalnej, więc dostajesz swoje IP w tej sieci. Jednak gdy próbujesz użyć usługi online, która odkryje twój adres IP, twój adres IP to adres IP routera twojego dostawcy usług lub coś podobnego. Używanie request.getRemoteAddr() jest poprawne. To właśnie robią takie usługi i nie mają innych udogodnień.

+0

Mój serwer (z serwletem) i mój klient działa na tym samym komputerze. Ale nie otrzymuję localhost jako IP, ponieważ klient używa prawdziwego adresu IP, gdy łączył się z serwerem. 188.xxx.xxx.158. Używałem go od teraz i działało idealnie, po raz pierwszy otrzymałem fałszywe IP. – TAR515

12

Kiedy masz NAT (Network Address Translation) urządzenie przed kontenerem serwletów request.getRemoteAddr() zwraca adres NAT, ponieważ inicjuje nowe połączenie:

Aby rozwiązać problem, powinieneś skonfigurować NAT do wysłania nagłówka adresu IP oryginalnego klienta Następnie, aby odebrać nagłówek z żądania. W przypadku konfiguracji w nagłówku NAT X-Forwarded-For ten kod: request.getHeader("X-Forwarded-For")

Funkcja jest prawidłowa, możesz jej użyć podczas konfigurowania NAT.

+0

Nie używam żadnego urządzenia NAT, jak wiem :) – TAR515

8

Java

String ip = request.getRemoteAddr(); 
if (ip.equalsIgnoreCase("0:0:0:0:0:0:0:1")) { 
    InetAddress inetAddress = InetAddress.getLocalHost(); 
    String ipAddress = inetAddress.getHostAddress(); 
    ip = ipAddress; 
} 
model.addAttribute("IP", ip); 

JSP <span><B>IP : <c:out value="${IP}" /></B></span> // Spring MAV 

JSP

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 
<%@ page import="java.net.InetAddress" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Displays Client IP Address</title> 
</head> 
<body> 
<% 
    // paste above java code 
out.println("<br><B>Clients IP : </B>"+ip); 
%> 
<span><br>Local Host : <%= request.getRemoteAddr() %></span> 
<span><br>ServerPort : <%= request.getServerPort() %></span> 
<span><br>Path  : <%= request.getRequestURI()%></span> 
</span> 
</body> 
</html> 

Jeśli JSP jest rozmieszczony w serwerze lokalnym i dostępu do tej JSP zwraca 0: 0: 0: 0: 0: 0: 0 : 1. Jeśli uzyskuje dostęp do aplikacji lokalnie przy pomocy ip, to zwraca IP.

RESTful Web Services z Jersey

@javax.ws.rs.Path("/ip") 
public class GetIPInfo { 

    @GET @Produces(MediaType.TEXT_PLAIN) 
    public Response getIP(@Context javax.servlet.http.HttpServletRequest request) throws UnknownHostException { 

     String remoteHost = request.getRemoteHost(); 
     String remoteAddr = request.getRemoteAddr(); 
     if (remoteAddr.equals("0:0:0:0:0:0:0:1")) { 
      InetAddress localip = java.net.InetAddress.getLocalHost(); 
      remoteAddr = localip.getHostAddress(); 
      remoteHost = localip.getHostName(); 
     } 
     int remotePort = request.getRemotePort(); 

     String msgoutput = remoteHost + " (" + remoteAddr + " : " + remotePort + ")"; 
     return Response.status(200).entity(msgoutput).build(); 
    } 
} 

przy użyciu JavaScript, aby znaleźćIP

Powiązane problemy