Je suis curieux de savoir s'il existe une bibliothèque qui gère déjà ce genre de choses, ou je dois le faire moi-même une fois de plus. Donc, la chose est que je veux obtenir le champ d'adresse IP de la demande d'en-tête HTTP des visiteurs sur mon serveur, et faire le tout en Java? Toute aide serait agréable. Merci d'avance.
Utilisez la méthode getHeader(String Name)
de la méthode javax.servlet.http.HttpServletRequest
objet pour récupérer la valeur de Remote_Addr
variable. Voici l exemple de code:
String ipAddress = request.getHeader("Remote_Addr");
Si ce code renvoie une chaîne vide, utilisez cette méthode:
String ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
if (ipAddress == null) {
ipAddress = request.getRemoteAddr();
}
Même s'il y a une réponse acceptée qui a été fortement votée, je voudrais suggérer une alternative et souligner les lacunes de la réponse acceptée.
request.getHeader("Remote_Addr")
est spécifié pour retourner exactement la même chose que request.getRemoteAddr()
. Par conséquent, cela n'a aucun sens de vérifier les deux. Notez également que getRemoteAddr
est une méthode de javax.servlet.ServletRequest
(c'est-à-dire agnostique HTTP) pendant que getHeader
est dans javax.servlet.http.HttpServletRequest
.
De plus, certains proxys utilisent Client-IP
plutôt que X-Forwarded-For
. Pour une discussion, voir https://stackoverflow.com/a/7446010/131929 .
Je ne sais pas à quel point l'utilisation de HTTP_X_FORWARDED_FOR
plus de X-Forwarded-For
est. Dans Java je préfère utiliser la forme directe et courte. Pour une discussion, voir https://stackoverflow.com/a/3834169/131929 . Haut/bas la casse ne fait aucune différence car getHeader
est spécifié pour être sensible à la casse in.
Alternative Java
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();
}
}
Alternative PHP
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;
}