Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 默认情况下,Compojure应用程序不发送CSRF_Clojure_Csrf_Compojure_Ring_Reagent - Fatal编程技术网

Clojure 默认情况下,Compojure应用程序不发送CSRF

Clojure 默认情况下,Compojure应用程序不发送CSRF,clojure,csrf,compojure,ring,reagent,Clojure,Csrf,Compojure,Ring,Reagent,我正在使用试剂和compojure制作一个玩具网络应用程序,我不明白为什么我的服务器没有发送CSRF cookie。其他答案和一些博客文章似乎暗示compojure的默认设置现在发送CSRF令牌,手动重新发送它实际上是一个bug。当我尝试点击POST/art端点时,我得到了403禁止响应。没有一个页面获得包含CSRF令牌的cookie,因此我无法将其与POST请求一起发送。有什么建议吗 ;;server.clj (ns my-app.server (:require [my-app.han

我正在使用试剂和compojure制作一个玩具网络应用程序,我不明白为什么我的服务器没有发送CSRF cookie。其他答案和一些博客文章似乎暗示compojure的默认设置现在发送CSRF令牌,手动重新发送它实际上是一个bug。当我尝试点击POST/art端点时,我得到了403禁止响应。没有一个页面获得包含CSRF令牌的cookie,因此我无法将其与POST请求一起发送。有什么建议吗

;;server.clj

(ns my-app.server
  (:require [my-app.handler :refer [app]]
            [environ.core :refer [env]]
            [ring.adapter.jetty :refer [run-jetty]])
  (:gen-class))

 (defn -main [& args]
   (let [port (Integer/parseInt (or (env :port) "3000"))]
     (run-jetty app {:port port :join? false})))

;; handler.clj

(ns my-app.handler
  (:require [compojure.core :refer [GET POST defroutes]]
            [compojure.route :refer [not-found resources]]
            [hiccup.page :refer [include-js include-css html5]]
            [my-app.middleware :refer [wrap-middleware]]
            [environ.core :refer [env]]))


(defroutes routes
  (GET "/" [] loading-page)
  (GET "/about" [] loading-page)
  (GET "/art" [] loading-page)
  (POST "/art" request {:sent (:body request) :hello "world"})

  (resources "/")
  (not-found "Not Found"))

(def app (wrap-middleware #'routes))


;;middleware.clj

(ns stagistry.middleware
  (:require [ring.middleware.defaults :refer [site-defaults wrap-defaults]]
            [prone.middleware :refer [wrap-exceptions]]
            [ring.middleware.reload :refer [wrap-reload]]))

(defn wrap-middleware [handler]
  (-> handler
      (wrap-defaults site-defaults)
      wrap-exceptions
      wrap-reload))

我把代码本身扔到github上,因为我仍然看不出哪里出了问题。

因此我找到了一个相关问题的答案,目前对我来说已经足够好了。我将middleware.clj站点默认值切换为不使用CSRF的api默认值。仍然很好奇如何让CSRF在这里工作,但这对我所做的并不重要。如果有人建议一个有效的修复方法,我会将其标记为正确的

其他答案和一些博客文章似乎暗示compojure的默认设置现在发送CSRF令牌,手动重新发送它实际上是一个bug

包装默认值站点默认值应用中间件。这将只向每个环浏览器会话添加一个CSRF令牌,并在POST请求中查找该令牌。如果令牌丢失,中间件将为请求返回403。将令牌添加到表单或ajax/任何post请求都取决于您,自由的代价是:

从文档中:

默认情况下,令牌应位于名为“_anti-forgery-token”的表单字段中,或位于“X-CSRF-token”或“X-XSRF-token”头中

例如,尝试添加此路由:

(GET "/someform" request (html5 (ring.util.anti-forgery/anti-forgery-field)))
防伪字段助手将添加一个隐藏的输入字段,该字段的值为CSRF令牌,如果表单已发布,则中间件将获取该字段。要直接访问令牌,您可以使用ring.middleware.anti-forgery/*anti-forgery-token*或在当前请求映射的会话中查找它:

(-> request :session :ring.middleware.anti-forgery/anti-forgery-token)
全局变量和辅助对象扩展到处理程序上下文,但不能从外部或同一上下文中的其他线程访问它

简单卷曲头示例:

获取CSRF令牌:

$ curl -v -c /tmp/cookiestore.txt http://localhost:3000/someform
通过标题设置令牌并发布一些内容:

$ curl -v -b /tmp/cookiestore.txt --header "X-CSRF-Token: ->token from prev. req<-" -X POST -d '{:foo "bar"}' localhost:3000/art

请发布wrap中间件的源代码,因为这是解决问题的关键部分。我的印象是CSRF处理是在wrap defaults站点defaults中完成的,但这种印象似乎是错误的。非常感谢您的指导:wrap默认值确实处理CSRF:您使用的是什么版本?compojure 1.4.0;刚刚更新到1.5.0,但没有解决问题。环默认值的版本是什么?包裹默认值就在那里。