如何在 ring-clojure 中获取客户端 IP 地址?

How to get the client IP address in ring-clojure?

当访问者提交表单时,我想关联输入他的 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)) 

但是这个returns{... :ip-address "0:0:0:0:0:0:0:1"}

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

从 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)))

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

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