We have Request.UserHostAddress
to get the IP address in ASP.NET, but this is usually the user’s ISP’s IP address, not exactly the user’s machine IP address who for example clicked a link. How can I get the real IP Address?
For example, in a Stack Overflow user profile it is: “Last account activity: 4 hours ago from 86.123.127.8”, but my machine IP address is a bit different. How does Stack Overflow get this address?
In some web systems there is an IP address check for some purposes. For example, with a certain IP address, for every 24 hours can the user just have only 5 clicks on download links? This IP address should be unique, not for an ISP that has a huge range of clients or Internet users.
Did I understand well?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Often you will want to know the IP address of someone visiting your website. While ASP.NET has several ways to do this one of the best ways we’ve seen is by using the “HTTP_X_FORWARDED_FOR” of the ServerVariables collection.
Here’s why…
Sometimes your visitors are behind either a proxy server or a router and the standard Request.UserHostAddress
only captures the IP address of the proxy server or router. When this is the case the user’s IP address is then stored in the server variable (“HTTP_X_FORWARDED_FOR”).
So what we want to do is first check “HTTP_X_FORWARDED_FOR” and if that is empty we then simply return ServerVariables("REMOTE_ADDR")
.
While this method is not foolproof, it can lead to better results. Below is the ASP.NET code in VB.NET, taken from James Crowley’s blog post “Gotcha: HTTP_X_FORWARDED_FOR returns multiple IP addresses”
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.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
Method 2
As others have said you can’t do what you are asking. If you describe the problem you are trying to solve maybe someone can help?
E.g.
- are you trying to uniquely identify your users?
- Could you use a cookie, or the session ID perhaps instead of the IP address?
Edit The address you see on the server shouldn’t be the ISP’s address, as you say that would be a huge range. The address for a home user on broadband will be the address at their router, so every device inside the house will appear on the outside to be the same, but the router uses NAT to ensure that traffic is routed to each device correctly. For users accessing from an office environment the address may well be the same for all users. Sites that use IP address for ID run the risk of getting it very wrong – the examples you give are good ones and they often fail. For example my office is in the UK, the breakout point (where I “appear” to be on the internet) is in another country where our main IT facility is, so from my office my IP address appears to be not in the UK. For this reason I can’t access UK only web content, such as the BBC iPlayer). At any given time there would be hundreds, or even thousands, of people at my company who appear to be accessing the web from the same IP address.
When you are writing server code you can never be sure what the IP address you see is referring to. Some users like it this way. Some people deliberately use a proxy or VPN to further confound you.
When you say your machine address is different to the IP address shown on StackOverflow, how are you finding out your machine address? If you are just looking locally using ipconfig
or something like that I would expect it to be different for the reasons I outlined above. If you want to double check what the outside world thinks have a look at whatismyipaddress.com/.
This Wikipedia link on NAT will provide you some background on this.
Method 3
UPDATE:
Thanks to Bruno Lopes. If several ip addresses could come then need to use this method:
private string GetUserIP() { string ipList = Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (!string.IsNullOrEmpty(ipList)) { return ipList.Split(',')[0]; } return Request.ServerVariables["REMOTE_ADDR"]; }
Method 4
If is c# see this way, is very simple
string clientIp = (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? Request.ServerVariables["REMOTE_ADDR"]).Split(',')[0].Trim();
Method 5
What else do you consider the user IP address? If you want the IP address of the network adapter, I’m afraid there’s no possible way to do it in a Web app. If your user is behind NAT or other stuff, you can’t get the IP either.
Update: While there are Web sites that use IP to limit the user (like rapidshare), they don’t work correctly in NAT environments.
Method 6
I think I should share my experience with you all. Well I see in some situations REMOTE_ADDR will NOT get you what you are looking for. For instance, if you have a Load Balancer behind the scene and if you are trying to get the Client’s IP then you will be in trouble. I checked it with my IP masking software plus I also checked with my colleagues being in different continents. So here is my solution.
When I want to know the IP of a client, I try to pick every possible evidence so I could determine if they are unique:
Here I found another sever-var that could help you all if you want to get exact IP of the client side. so I am using : HTTP_X_CLUSTER_CLIENT_IP
HTTP_X_CLUSTER_CLIENT_IP always gets you the exact IP of the client. In any case if its not giving you the value, you should then look for HTTP_X_FORWARDED_FOR as it is the second best candidate to get you the client IP and then the REMOTE_ADDR var which may or may not return you the IP but to me having all these three is what I find the best thing to monitor them.
I hope this helps some guys.
Method 7
You can use:
System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList.GetValue(0).ToString();
Method 8
IP addresses are part of the Network layer in the “seven-layer stack”. The Network layer can do whatever it wants to do with the IP address. That’s what happens with a proxy server, NAT, relay, or whatever.
The Application layer should not depend on the IP address in any way. In particular, an IP Address is not meant to be an identifier of anything other than the idenfitier of one end of a network connection. As soon as a connection is closed, you should expect the IP address (of the same user) to change.
Method 9
All of the responses so far take into account the non-standardized, but very common, X-Forwarded-For
header. There is a standardized Forwarded
header which is a little more difficult to parse out. Some examples are as follows:
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
I have written a class that takes both of these headers into account when determining a client’s IP address.
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; } } }
Below are some unit tests that I used to validate my solution:
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; } } } }
Method 10
If you are using CloudFlare,
you can try this Extension Method:
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; } }
then
string IPAddress = Request.GetIPAddress();
Method 11
string IP = HttpContext.Current.Request.Params["HTTP_CLIENT_IP"] ?? HttpContext.Current.Request.UserHostAddress;
Method 12
What you can do is store the router IP of your user and also the forwarded IP and try to make it reliable using both the IPs [External Public and Internal Private]. But again after some days client may be assigned new internal IP from router but it will be more reliable.
Method 13
Combining the answers from @Tony and @mangokun, I have created the following extension method:
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; } }
Method 14
public static class Utility { public static string GetClientIP(this System.Web.UI.Page page) { string _ipList = page.Request.Headers["CF-CONNECTING-IP"].ToString(); if (!string.IsNullOrWhiteSpace(_ipList)) { return _ipList.Split(',')[0].Trim(); } else { _ipList = page.Request.ServerVariables["HTTP_X_CLUSTER_CLIENT_IP"]; if (!string.IsNullOrWhiteSpace(_ipList)) { return _ipList.Split(',')[0].Trim(); } else { _ipList = page.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (!string.IsNullOrWhiteSpace(_ipList)) { return _ipList.Split(',')[0].Trim(); } else { return page.Request.ServerVariables["REMOTE_ADDR"].ToString().Trim(); } } } } }
Use;
string _ip = this.GetClientIP();
Method 15
use in ashx file
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"]; }
Method 16
In NuGet package install Microsoft.AspNetCore.HttpOverrides
Then try:
public class ClientDeviceInfo { private readonly IHttpContextAccessor httpAccessor; public ClientDeviceInfo(IHttpContextAccessor httpAccessor) { this.httpAccessor = httpAccessor; } public string GetClientLocalIpAddress() { return httpAccessor.HttpContext.Connection.LocalIpAddress.ToString(); } public string GetClientRemoteIpAddress() { return httpAccessor.HttpContext.Connection.RemoteIpAddress.ToString(); } public string GetClientLocalPort() { return httpAccessor.HttpContext.Connection.LocalPort.ToString(); } public string GetClientRemotePort() { return httpAccessor.HttpContext.Connection.RemotePort.ToString(); } }
Method 17
Its easy.Try it:
var remoteIpAddress = Request.HttpContext.Connection.RemoteIpAddress;
just it :))
Method 18
Simply
var ip = Request.UserHostAddress;
That’s all…
Method 19
use this
Dns.GetHostEntry(Dns.GetHostName())
Method 20
Hello guys Most of the codes you will find will return you server ip address not client ip address .however this code returns correct client ip address.Give it a try.
For More info just check this
https://www.youtube.com/watch?v=Nkf37DsxYjI
for getting your local ip address using javascript you can use
put this code inside your script tag
<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('rn').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>
and For getting your public ip address you can use
put this code inside your script tag
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>
Method 21
Try:
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; }
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0