【问题标题】:How to get the client IP address in ring-clojure?如何在 ring-clojure 中获取客户端 IP 地址?
【发布时间】:2015-05-03 18:56:58
【问题描述】:

当访问者提交表单时,我想关联输入他的 IP 地址。

(POST "/form" {params :params} (assoc params :ip-address the-ip)

如何做到这一点?

想过这样做:

(POST "/form" {params    :params
               client-ip :remote-addr} 
      (->> params keywordize-keys (merge {:ip-address client-ip}) str)) 

但这会返回{... :ip-address "0:0:0:0:0:0:0:1"}

【问题讨论】:

  • 这是 ipv6 中的 localhost。您的请求来自哪里?
  • @cfrick 本地主机。是的。我无法在 prod 中对此进行测试,因此不确定 :remote-addr 是否会形成您的答案,我想这是正确的。
  • 顺便说一句,我发现我不需要使用关键字化键 fn。只需要 wrap-keyword-paramsstackoverflow.com/questions/26151801/…

标签: clojure ring


【解决方案1】:

从 Arthur Ulfeldt 的评论到 Bill 的回答,我想我们可以这样写:

(defn get-client-ip [req]
  (if-let [ips (get-in req [:headers "x-forwarded-for"])]
    (-> ips (clojure.string/split #",") first)
    (:remote-addr req)))

【讨论】:

  • // ,这会返回一个 IPv6 地址吗?
  • @NathanBasanese 如果我正确地回答了你的问题,我的回答是我没有从 IPV6 源进行测试。我不知道它是否会正确返回这样的字符串..
【解决方案2】:

从请求对象获取:remote-addr 通常是正确的方法,除非您坐在负载平衡器后面。在这种情况下,您的负载平衡可能会添加一个标头,例如x-forwarded-for 请求。这会让这样的事情变得合适。

(or (get-in request [:headers "x-forwarded-for"]) (:remote-addr request))

【讨论】:

  • 这对于本身位于代理后面的客户端将失败,因为 x-forwarded-for 将是一个逗号分隔的 IP 列表,例如“2.2.2.2,5.5.5.5”,其中包含您的实际地址想要所有之前第一个, 并记住它们也可以是IPv6 地址,即使您的服务在IPv4 上
【解决方案3】:

我很确定您可以从响铃请求对象中获取此信息。看看 ring.middleware.dump (handle-dump) 包。如果你设置了它和一个简单的使用它的路线,你会得到一个漂亮的网页,显示一个响铃请求对象中提供的所有可用值。很确定这包括客户端 IP 地址。由于此信息是从 http 标头中获取的,因此它可能比手动将其放入您的请求参数中更可靠 - 使用表单或 json 将其放入您的请求参数中可能意味着它更容易伪造。此外,如果它已经作为请求对象的一部分随时可用,则意味着您需要做的事情更少。

【讨论】:

    猜你喜欢
    • 2012-03-14
    • 2012-02-16
    • 2019-01-14
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多