我们有请求。UserHostAddress在ASP. ASP. ASP中获取IP地址。NET,但这通常是用户的ISP的IP地址,而不是用户点击链接的机器IP地址。如何获取真实IP地址?
例如,在Stack Overflow用户配置文件中,它是:“上次帐户活动:4小时前从86.123.127.8开始”,但我的机器IP地址有点不同。Stack Overflow如何获得这个地址?
在一些web系统中,出于某些目的有一个IP地址检查。例如,对于某个IP地址,每24小时用户只能点击5次下载链接吗?这个IP地址应该是唯一的,而不是针对一个拥有大量客户端或互联网用户的ISP。
我听懂了吗?
通常你会想知道访问你网站的人的IP地址。而ASP。NET有几种方法可以做到这一点,我们所见过的最好的方法之一是使用ServerVariables集合的“HTTP_X_FORWARDED_FOR”。
这是为什么…
有时,您的访问者位于代理服务器或路由器和标准请求的后面。UserHostAddress仅捕获代理服务器或路由器的IP地址。在这种情况下,用户的IP地址存储在服务器变量(“HTTP_X_FORWARDED_FOR”)中。
所以我们要做的是首先检查“HTTP_X_FORWARDED_FOR”,如果这是空的,我们然后简单地返回ServerVariables(“REMOTE_ADDR”)。
虽然这种方法不是万无一失的,但它可以带来更好的结果。下面是ASP。NET代码在VB。NET,摘自James Crowley的博客文章“Gotcha: HTTP_X_FORWARDED_FOR返回多个IP地址”
C#
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。网
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
到目前为止,所有的响应都考虑了非标准化但非常常见的X-Forwarded-For报头。有一个标准化的转发头,它有点难以解析。一些例子如下:
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
我已经编写了一个类,在确定客户端的IP地址时考虑这两个头。
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;
}
}
}
下面是我用来验证我的解决方案的一些单元测试:
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; }
}
}
}
通常你会想知道访问你网站的人的IP地址。而ASP。NET有几种方法可以做到这一点,我们所见过的最好的方法之一是使用ServerVariables集合的“HTTP_X_FORWARDED_FOR”。
这是为什么…
有时,您的访问者位于代理服务器或路由器和标准请求的后面。UserHostAddress仅捕获代理服务器或路由器的IP地址。在这种情况下,用户的IP地址存储在服务器变量(“HTTP_X_FORWARDED_FOR”)中。
所以我们要做的是首先检查“HTTP_X_FORWARDED_FOR”,如果这是空的,我们然后简单地返回ServerVariables(“REMOTE_ADDR”)。
虽然这种方法不是万无一失的,但它可以带来更好的结果。下面是ASP。NET代码在VB。NET,摘自James Crowley的博客文章“Gotcha: HTTP_X_FORWARDED_FOR返回多个IP地址”
C#
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。网
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
大家好,你会发现大多数代码将返回你的服务器ip地址而不是客户端ip地址。然而,这段代码返回正确的客户端ip地址。试一试。
更多信息,请检查这个
https://www.youtube.com/watch?v=Nkf37DsxYjI
对于使用javascript获取本地IP地址,您可以使用
将这段代码放在脚本标记中
<script>
var RTCPeerConnection = /*window.RTCPeerConnection ||*/
window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
if (RTCPeerConnection) (function () {
var rtc = new RTCPeerConnection({ iceServers: [] });
if (1 || window.mozRTCPeerConnection) {
rtc.createDataChannel('', { reliable: false });
};
rtc.onicecandidate = function (evt) {
if (evt.candidate)
grepSDP("a=" + evt.candidate.candidate);
};
rtc.createOffer(function (offerDesc) {
grepSDP(offerDesc.sdp);
rtc.setLocalDescription(offerDesc);
}, function (e) { console.warn("offer failed", e); });
var addrs = Object.create(null);
addrs["0.0.0.0"] = false;
function updateDisplay(newAddr) {
if (newAddr in addrs) return;
else addrs[newAddr] = true;
var displayAddrs = Object.keys(addrs).filter(function
(k) { return addrs[k]; });
document.getElementById('list').textContent =
displayAddrs.join(" or perhaps ") || "n/a";
}
function grepSDP(sdp) {
var hosts = [];
sdp.split('\r\n').forEach(function (line) {
if (~line.indexOf("a=candidate")) {
var parts = line.split(' '),
addr = parts[4],
type = parts[7];
if (type === 'host') updateDisplay(addr);
} else if (~line.indexOf("c=")) {
var parts = line.split(' '),
addr = parts[2];
updateDisplay(addr);
}
});
}
})(); else
{
document.getElementById('list').innerHTML = "<code>ifconfig| grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>";
document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull.";
}
</script>
<body>
<div id="list"></div>
</body>
和获取您的公共ip地址,您可以使用
将这段代码放在脚本标记中
function getIP(json) {
document.write("My public IP address is: ", json.ip);
}
<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getIP"></script>