如何从调用对象中获取 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 地址的主要内容,如果未能解决你的问题,请参考以下文章