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

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

call.request.origin.remoteHost

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

【问题讨论】:

    标签: kotlin ktor


    【解决方案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")
      }
      

      【讨论】:

        猜你喜欢
        • 2010-11-04
        • 2021-07-04
        • 1970-01-01
        • 2010-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-26
        相关资源
        最近更新 更多