如何从调用对象中获取 IP 地址

Posted

技术标签:

【中文标题】如何从调用对象中获取 IP 地址【英文标题】:How to get ip address from call object 【发布时间】:2021-02-05 11:42:27 【问题描述】:

我将 Ktor 用于后端服务,我想记录传入的请求。我已经安装了这个功能,一切都很好,但是我怎样才能获得远程 IP 地址呢?

call.request.origin.remoteHost

我使用这一行,但我得到的是主机名,而不是 IP。我使用 InetAddress 类中的标准 getByName 方法来获取 IP。 有没有更好的办法?

【问题讨论】:

【参考方案1】:

您不能对 Ktor 执行此操作,因为从域解析 IP 地址不是 Ktor 的工作。

不过,您可以使用 Java 的 InetAddress:

val url = "http://google.com"; 
val ip =  Inet4Address.getByName(url);

【讨论】:

【参考方案2】:

取决于您希望此信息有多准确。

如果您通读 Ktor 代码,您会发现 remoteHost 实际上是从 HTTP X-Forwarded-Host 标头设置的。

来自 API 文档:

* NEVER use it for user authentication as it can be easily falsified (user  can simply set some HTTP headers
* such as X-Forwarded-Host so you should NEVER rely on it in any security checks.
* If you are going to use it to create a back-connection please do it with care as an offender can easily
* use it to force you to connect to some host that is not intended to be connected to so that may cause
* serious consequences.

更好的方法可能是从应用程序引擎本身获取 IP。不幸的是,ApplicationCall 本身是私有的,所以你必须求助于反射,这不是最佳的:

class RoutingApplicationCall(private val call: ApplicationCall,

不过,这是可能的:


// Getting the private field through reflection
val f = context::class.memberProperties.find  it.name == "call" 

f?.let 
    // Making it accessible
    it.isAccessible = true
    val w = it.getter.call(context) as NettyApplicationCall

    // Getting the remote address 
    val ip: SocketAddress? = w.request.context.pipeline().channel().remoteAddress()
    println("IP: $ip")

【讨论】:

以上是关于如何从调用对象中获取 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章

如何从 sockaddr 获取 IP 地址

如何使用 GeoIP2() django 模型从 IP 地址调用中提取保存的信息以显示在我的 html 中

在 RPC 调用中确定请求者的 IP 地址

如何在 Rails 中获取客户的 IP 地址?

glib从路由获取IP地址

Java如何从域名中获取IP地址?