如何在 ASP.NET Core 2.1 中获取客户端 IP 地址
Posted
技术标签:
【中文标题】如何在 ASP.NET Core 2.1 中获取客户端 IP 地址【英文标题】:How to get Client IP address in ASP.NET Core 2.1 【发布时间】:2018-06-30 15:57:12 【问题描述】:我正在使用 Microsoft Visual Studio 2017 提供的 Angular 模板开发 ASP.Net Core 2.1。我的客户端应用程序运行良好。用户认证竞争后,我想启动存储客户端用户 IP 地址的用户会话管理。我已经在互联网上搜索过这个,但到目前为止还没有找到任何解决方案。
以下是我已经访问过的一些参考链接:
How do I get client IP address in ASP.NET CORE?
Get Client IP Address in ASP.NET Core 2.0
Get a user remote IP Address in ASP.Net Core
在我的 ValuesController.cs 中,我还尝试了以下代码:
private IHttpContextAccessor _accessor;
public ValuesController(IHttpContextAccessor accessor)
_accessor = accessor;
public IEnumerable<string> Get()
var ip = Request.HttpContext.Connection.RemoteIpAddress.ToString();
return new string[] ip, "value2" ;
其中 ip 变量我得到空值并出现此错误
Request.HttpContext.Connection.RemoteIpAddress.Address 抛出类型为“System.Net.Sockets.SocketException”的异常
请告诉我。
【问题讨论】:
如果你使用_accessor.HttpContext.Connection.RemoteIpAddress
也是null
吗?
您是否尝试通过 IP 地址来识别用户?那是不可靠的。您网站上的两个人在图书馆、咖啡店、酒店等处连接到公共 wifi 将具有相同的 IP 地址。
你怎么称呼这段代码?你应该可以在控制器中只做HttpContext.Connection.RemoteIpAddress
。无需通过Request
或在那里使用 HttpContextAccessor。
如何解析远程ip地址与宿主环境的具体情况有很大关系docs.microsoft.com/en-us/aspnet/core/host-and-deploy/…
@poke 你的解决方案在我的情况下不起作用。
【参考方案1】:
在您的Startup.cs
中,确保您有一个ConfigureServices 方法,传入IServiceCollection
,然后将IHttpContextAccessor
注册为单例,如下所示:
public void ConfigureServices(IServiceCollection services)
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
在Startup.cs
文件中注册IHttpContextAccessor
后,您可以在控制器类中注入IHttpContextAccessor
并像这样使用它:
private IHttpContextAccessor _accessor;
public ValuesController(IHttpContextAccessor accessor)
_accessor = accessor;
public IEnumerable<string> Get()
var ip = _accessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
return new string[] ip, "value2" ;
【讨论】:
ToString 值对我来说是 "::1" 在 localhost 机器上运行时。return new string[] ip, "value2" ;
中的value2
的目的是什么?
value2
只是在这里返回以匹配初始问题中提供的代码,并且不用于检索客户端 IP 的任何目的。同样的块也可以写成如下:public string Get() return _accessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
【参考方案2】:
可以使用以下代码:
services.Configure<ForwardedHeadersOptions>(options =>
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
);
string remoteIpAddress = HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
if (Request.Headers.ContainsKey("X-Forwarded-For"))
remoteIpAddress = Request.Headers["X-Forwarded-For"];
【讨论】:
你的回答和使用有什么区别:app.UseForwardedHeaders(new ForwardedHeadersOptionsForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto); ? @desmati,如果我不检查 Request.Headers.ContainsKey("X-Forwarded-For") ,即使我只使用 app.UseForwardedHeaders(new ForwardedHeadersOptionsForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto); @Liam,我也有同样的问题。根据文章 docs.microsoft.com/en-us/aspnet/core/host-and-deploy/… ,它应该直接从 context.Connection.RemoteIpAddress 工作。不幸的是,我还必须从 context.Request.Headers[_xForwardedForHeader] 获取客户端 IP。 “x-forwarded-for”标头还可以包含托管它的网站的端口(例如 10.0.120:6529)。要删除它(假设它是 IPv4 地址),您可以使用以下命令来删除它:remoteIpAddress = Request.Headers["X-Forwarded-For"].ToString().Split(":")[0]; 【参考方案3】:如果您的 Kestrel 位于 IIS 等反向代理之后,请确保转发包含客户端 IP 的标头。 这进入启动:
app.UseForwardedHeaders(new ForwardedHeadersOptionsForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto);
【讨论】:
【参考方案4】:如果我使用绑定地址 Localhost:5000,那么 IP 将返回为“::1”(Localhost IPv6 地址)。 如果我在 IP 地址上绑定我的 Webapi 并尝试从另一台客户端计算机访问它,我会在 API 响应中获得客户端的 IP 地址。 我相信不需要 HTTPAccessor。根据文档https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.1,HttpContext.Connection.RemoteIpAddress 由 XForwardedFor 标头设置。
如果您的应用程序 (WEBAPI) 位于 nginx/Apache 反向代理之后,如果您未设置或处理 X-Forwarded-For Header,那么您总是会得到 Nulls 或 Reverse-Proxy Server 的 IP 地址。
上面的 GetHostEntry 与 HTTP 请求没有直接关系。 GetHostEntry 只是一个用于 API 编程的 NSLookup 工具,它只告诉您特定名称可访问的 IP 地址,但不会告诉您请求来自哪个 IP 地址到 WebApi。
希望有帮助
【讨论】:
【参考方案5】:试试这个代码,
var ipAddress = HttpContext.Connection.RemoteIpAddress;
如果您在同一个 LAN 中有另一台计算机,请尝试与这台计算机连接,但使用用户 ip 而不是 localhost。否则,您将始终得到 ::1 结果。
【讨论】:
【参考方案6】:花了一些时间搜索后,我找到了自己的问题答案。在这里,我还分享了源链接,从中可以获得我的答案和详细说明,以了解如何查询服务器以获取家庭地址和它支持的 IP 地址。
代码:
IPHostEntry heserver = Dns.GetHostEntry(Dns.GetHostName());
var ip = heserver.AddressList[2].ToString();
Source
这是我的另一个Question: How to access server variables in ASP.Net Core 2.x希望这对大家有帮助。
【讨论】:
我不确定是否理解。这很有趣,但在我看来,您的答案没有提供来自正在查询您的服务器的客户端的 client ip 地址,这是您的问题。 你的意思是说上面的代码没有返回客户端IP地址?也许你是对的,因为我使用的是 localhost,也许它会返回一个服务器 IP 地址。 是的,好像是来自服务端(应用的Host)的地址,对应服务端的DNS信息,所以可能和客户端完全无关。跨度> @Pac0 那么我现在能做什么呢?如何获取客户端 IP 地址? 我还是不知道,很遗憾。在我知道的所有情况下,HttpContext.Connection.RemoteIpAddress
都是可行的方法,但由于某种原因,它显然对你不起作用。【参考方案7】:
这对我有用 .Net Core 2.2
:
IPHostEntry heserver = Dns.GetHostEntry(Dns.GetHostName());
var ipAddress = heserver.AddressList.ToList().Where(p => p.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).FirstOrDefault().ToString();
【讨论】:
你能解释一下这是如何提供客户端IP地址的吗? 提供服务器IP而不是客户端IP以上是关于如何在 ASP.NET Core 2.1 中获取客户端 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章
直接从令牌获取 JWT 声明,ASP Net Core 2.1
如何在 asp.net core 2.1 中使用自定义消息设置状态代码?
如何在 ASP.NET Core 2.1 中使用自动完成输入引发模式
如何在 ASP.NET Core 2.1 中的计时器上运行 BackgroundService