real - obtener ip cliente c#
¿Cómo obtener la dirección IP del cliente de un usuario en ASP.NET? (16)
¿Qué más consideras la dirección IP del usuario? Si desea la dirección IP del adaptador de red, me temo que no hay forma posible de hacerlo en una aplicación web. Si su usuario está detrás de NAT u otras cosas, tampoco puede obtener la IP.
Actualización : si bien hay sitios web que usan IP para limitar al usuario (como rapidshare), no funcionan correctamente en entornos NAT.
Tenemos Request.UserHostAddress
para obtener la dirección IP en ASP.NET, pero generalmente es la dirección IP del ISP del usuario, no exactamente la dirección IP de la máquina del usuario que, por ejemplo, hizo clic en un enlace. ¿Cómo puedo obtener la dirección IP real?
Por ejemplo, en un perfil de usuario de desbordamiento de pila es: "Última actividad de la cuenta: hace 4 horas desde 86.123.127.8" , pero la dirección IP de mi máquina es un poco diferente. ¿Cómo obtiene Stack Overflow esta dirección?
En algunos sistemas web hay una verificación de dirección IP para algunos propósitos. Por ejemplo, con una determinada dirección IP, por cada 24 horas, ¿puede el usuario tener solo 5 clics en los enlaces de descarga? Esta dirección IP debe ser única, no para un ISP que tenga una gran variedad de clientes o usuarios de Internet.
¿Lo entendí bien?
A menudo, querrá saber la dirección IP de alguien que visita su sitio web. Si bien ASP.NET tiene varias formas de hacer esto, una de las mejores formas que hemos visto es mediante el uso de "HTTP_X_FORWARDED_FOR" de la colección ServerVariables.
Este es el por qué...
A veces, sus visitantes están detrás de un servidor proxy o un enrutador, y la Request.UserHostAddress
estándar.UsuarioHostAddress solo captura la dirección IP del servidor proxy o enrutador. Cuando este es el caso, la dirección IP del usuario se almacena en la variable del servidor ("HTTP_X_FORWARDED_FOR").
Entonces, lo que queremos hacer es primero verificar "HTTP_X_FORWARDED_FOR" y si eso está vacío, simplemente devolvemos ServerVariables("REMOTE_ADDR")
.
Si bien este método no es infalible, puede conducir a mejores resultados. A continuación se muestra el código ASP.NET en VB.NET, tomado de la publicación del blog de James Crowley "Gotcha: HTTP_X_FORWARDED_FOR devuelve varias direcciones IP"
DO#
protected string GetIPAddress()
{
System.Web.HttpContext context = System.Web.HttpContext.Current;
string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipAddress))
{
string[] addresses = ipAddress.Split('','');
if (addresses.Length != 0)
{
return addresses[0];
}
}
return context.Request.ServerVariables["REMOTE_ADDR"];
}
VB.NET
Public Shared Function GetIPAddress() As String
Dim context As System.Web.HttpContext = System.Web.HttpContext.Current
Dim sIPAddress As String = context.Request.ServerVariables("HTTP_X_FORWARDED_FOR")
If String.IsNullOrEmpty(sIPAddress) Then
Return context.Request.ServerVariables("REMOTE_ADDR")
Else
Dim ipArray As String() = sIPAddress.Split(New [Char]() {","c})
Return ipArray(0)
End If
End Function
Combinando las respuestas de @Tony y @mangokun , he creado el siguiente método de extensión:
public static class RequestExtensions
{
public static string GetIPAddress(this HttpRequest Request)
{
if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();
if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
{
string ipAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipAddress))
{
string[] addresses = ipAddress.Split('','');
if (addresses.Length != 0)
{
return addresses[0];
}
}
}
return Request.UserHostAddress;
}
}
Como otros han dicho, no puedes hacer lo que estás pidiendo. Si describe el problema que está tratando de resolver, ¿quizás alguien pueda ayudarlo? Por ejemplo, ¿estás tratando de identificar de forma única a tus usuarios? ¿Podría usar una cookie o el ID de sesión en lugar de la dirección IP?
Editar La dirección que ve en el servidor no debe ser la dirección del ISP, ya que dice que sería un rango enorme. La dirección para un usuario doméstico en banda ancha será la dirección en su enrutador, por lo que todos los dispositivos dentro de la casa aparecerán en el exterior para que sean iguales, pero el enrutador usa NAT para garantizar que el tráfico se enrute a cada dispositivo correctamente. Para los usuarios que acceden desde un entorno de oficina, la dirección puede ser la misma para todos los usuarios. Los sitios que utilizan la dirección IP para la identificación corren el riesgo de equivocarse: los ejemplos que da son buenos y con frecuencia fallan. Por ejemplo, mi oficina está en el Reino Unido, el punto de ruptura (donde "aparentemente" estoy en Internet) es en otro país donde se encuentra nuestra principal instalación de TI, por lo que desde mi oficina mi dirección IP parece no estar en el Reino Unido. Por este motivo, no puedo acceder al contenido web exclusivo del Reino Unido, como BBC iPlayer). En un momento dado, habría cientos, o incluso miles, de personas en mi empresa que parecen estar accediendo a la web desde la misma dirección IP.
Cuando escribe el código del servidor, nunca puede estar seguro de a qué dirección IP se refiere. A algunos usuarios les gusta de esta manera. Algunas personas usan deliberadamente un proxy o VPN para confundirlo aún más.
Cuando dice que la dirección de su máquina es diferente a la dirección IP que se muestra en , ¿cómo está averiguando la dirección de su máquina? Si solo está buscando localmente usando ipconfig
o algo así, esperaría que fuera diferente por las razones que mencioné anteriormente. Si desea volver a verificar lo que el mundo exterior cree, eche un vistazo a whatismyipaddress.com/ .
Este enlace de Wikipedia en NAT le proporcionará algunos antecedentes sobre esto.
Creo que debería compartir mi experiencia con todos ustedes. Bueno, veo que en algunas situaciones, REMOTE_ADDR NO te dará lo que estás buscando. Por ejemplo, si tiene un Load Balancer detrás de la escena y si está tratando de obtener la IP del cliente, entonces estará en problemas. Lo verifiqué con mi software de enmascaramiento de IP y también verifiqué que mis colegas estaban en diferentes continentes. Así que aquí está mi solución.
Cuando quiero saber la IP de un cliente, trato de seleccionar cada evidencia posible para poder determinar si son únicas:
Aquí encontré otro sever-var que podría ayudarlos a todos si desean obtener la IP exacta del lado del cliente. entonces estoy usando: HTTP_X_CLUSTER_CLIENT_IP
HTTP_X_CLUSTER_CLIENT_IP siempre le proporciona la IP exacta del cliente. En cualquier caso, si no le está dando el valor, debe buscar HTTP_X_FORWARDED_FOR ya que es el segundo mejor candidato para obtener la IP del cliente y luego la var REMOTE_ADDR que puede o no devolverle la IP, pero a mi me parece que tiene todas estas Tres es lo que encuentro lo mejor para monitorearlos.
Espero que esto ayude a algunos chicos.
Las direcciones IP son parte de la capa de red en la "pila de siete capas". La capa de red puede hacer lo que quiera con la dirección IP. Eso es lo que sucede con un servidor proxy, NAT, relé o lo que sea.
La capa de aplicación no debe depender de la dirección IP de ninguna manera. En particular, una dirección IP no pretende ser un identificador de otra cosa que no sea el identificador de un extremo de una conexión de red. Tan pronto como se cierre una conexión, debe esperar que cambie la dirección IP (del mismo usuario).
Lo que puede hacer es almacenar la IP del enrutador de su usuario y también la IP reenviada e intentar que sea confiable utilizando tanto las IP [Público externo e Privado interno]. Pero nuevamente, después de algunos días, al cliente se le puede asignar una nueva IP interna desde el enrutador, pero será más confiable.
Puedes usar:
System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList.GetValue(0).ToString();
Si es c # ver de esta manera, es muy simple.
string clientIp = (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ??
Request.ServerVariables["REMOTE_ADDR"]).Split('','')[0].Trim();
Si está utilizando CloudFlare, puede probar este método de extensión :
public static class IPhelper
{
public static string GetIPAddress(this HttpRequest Request)
{
if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();
if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) return Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
return Request.UserHostAddress;
}
}
entonces
string IPAddress = Request.GetIPAddress();
Todas las respuestas hasta el momento tienen en cuenta el encabezado X-Forwarded-For
no estandarizado, pero muy común. Hay un encabezado Forwarded
estandarizado que es un poco más difícil de analizar. Algunos ejemplos son los siguientes:
Forwarded: for="_gazonk"
Forwarded: For="[2001:db8:cafe::17]:4711"
Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43
Forwarded: for=192.0.2.43, for=198.51.100.17
He escrito una clase que tiene en cuenta estos dos encabezados al determinar la dirección IP de un cliente.
using System;
using System.Web;
namespace Util
{
public static class IP
{
public static string GetIPAddress()
{
return GetIPAddress(new HttpRequestWrapper(HttpContext.Current.Request));
}
internal static string GetIPAddress(HttpRequestBase request)
{
// handle standardized ''Forwarded'' header
string forwarded = request.Headers["Forwarded"];
if (!String.IsNullOrEmpty(forwarded))
{
foreach (string segment in forwarded.Split('','')[0].Split('';''))
{
string[] pair = segment.Trim().Split(''='');
if (pair.Length == 2 && pair[0].Equals("for", StringComparison.OrdinalIgnoreCase))
{
string ip = pair[1].Trim(''"'');
// IPv6 addresses are always enclosed in square brackets
int left = ip.IndexOf(''[''), right = ip.IndexOf('']'');
if (left == 0 && right > 0)
{
return ip.Substring(1, right - 1);
}
// strip port of IPv4 addresses
int colon = ip.IndexOf('':'');
if (colon != -1)
{
return ip.Substring(0, colon);
}
// this will return IPv4, "unknown", and obfuscated addresses
return ip;
}
}
}
// handle non-standardized ''X-Forwarded-For'' header
string xForwardedFor = request.Headers["X-Forwarded-For"];
if (!String.IsNullOrEmpty(xForwardedFor))
{
return xForwardedFor.Split('','')[0];
}
return request.UserHostAddress;
}
}
}
A continuación hay algunas pruebas unitarias que utilicé para validar mi solución:
using System.Collections.Specialized;
using System.Web;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UtilTests
{
[TestClass]
public class IPTests
{
[TestMethod]
public void TestForwardedObfuscated()
{
var request = new HttpRequestMock("for=/"_gazonk/"");
Assert.AreEqual("_gazonk", Util.IP.GetIPAddress(request));
}
[TestMethod]
public void TestForwardedIPv6()
{
var request = new HttpRequestMock("For=/"[2001:db8:cafe::17]:4711/"");
Assert.AreEqual("2001:db8:cafe::17", Util.IP.GetIPAddress(request));
}
[TestMethod]
public void TestForwardedIPv4()
{
var request = new HttpRequestMock("for=192.0.2.60;proto=http;by=203.0.113.43");
Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
}
[TestMethod]
public void TestForwardedIPv4WithPort()
{
var request = new HttpRequestMock("for=192.0.2.60:443;proto=http;by=203.0.113.43");
Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
}
[TestMethod]
public void TestForwardedMultiple()
{
var request = new HttpRequestMock("for=192.0.2.43, for=198.51.100.17");
Assert.AreEqual("192.0.2.43", Util.IP.GetIPAddress(request));
}
}
public class HttpRequestMock : HttpRequestBase
{
private NameValueCollection headers = new NameValueCollection();
public HttpRequestMock(string forwarded)
{
headers["Forwarded"] = forwarded;
}
public override NameValueCollection Headers
{
get { return this.headers; }
}
}
}
utilizar en el archivo ashx
public string getIP(HttpContext c)
{
string ips = c.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ips))
{
return ips.Split('','')[0];
}
return c.Request.ServerVariables["REMOTE_ADDR"];
}
utilizar esta
Dns.GetHostEntry(Dns.GetHostName())
ACTUALIZACIÓN: Gracias a Bruno Lopes. Si varias direcciones IP pueden venir, entonces necesitas usar este método:
private string GetUserIP()
{
string ipList = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (!string.IsNullOrEmpty(ipList))
{
return ipList.Split('','')[0];
}
return Request.ServerVariables["REMOTE_ADDR"];
}
Tratar:
using System.Net;
public static string GetIpAddress() // Get IP Address
{
string ip = "";
IPHostEntry ipEntry = Dns.GetHostEntry(GetCompCode());
IPAddress[] addr = ipEntry.AddressList;
ip = addr[2].ToString();
return ip;
}
public static string GetCompCode() // Get Computer Name
{
string strHostName = "";
strHostName = Dns.GetHostName();
return strHostName;
}
string IP = HttpContext.Current.Request.Params["HTTP_CLIENT_IP"] ?? HttpContext.Current.Request.UserHostAddress;