无法在Clojure中完成POST请求

时间:2015-10-14 17:43:54

标签: post clojure compojure antiforgerytoken

我最近开始探索Clojure,我想建立一个具有基本CRUD功能的简单Web应用程序。我在这里找到了一个很好的教程:http://www.xuan-wu.com/2013-09-21-Basic-Web-Application-in-Clojure

GET请求工作正常,但每当我尝试发布请求时,都会收到以下错误:

Invalid anti-forgery token

我之前提到的教程没有解决任何与安全相关的问题。我做了一些挖掘,似乎我错过了Compojure的一些组件,它应该生成一个用于发出POST请求的令牌。有些地方提到我应该自动发生,而我没有任何改变。我仍然不确定我失踪了什么。这是我的代码:

(ns myblog.handler
    (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
            [myblog.views :as views]
            [myblog.posts :as posts]
            [ring.util.response :as resp]
            [ring.middleware.basic-authentication :refer :all]))

(defn authenticated? [name pass]
  (and (= name "user")
       (= pass "pass")))

(defroutes public-routes
    (GET "/" [] (views/main-page))
    (route/resources "/"))

(defroutes protected-routes
    (GET "/admin" [] (views/admin-page))
    (GET "/admin/add" [] (views/add-post))
    (POST "/admin/create" [& params]
        (do (posts/create params)
            (resp/redirect "/admin"))))

(defroutes app-routes
    public-routes
    (wrap-basic-authentication protected-routes authenticated?)
    (route/not-found "Not Found"))

(def app
  (wrap-defaults app-routes site-defaults))

同样,只有POST请求" / admin / create"失败时出现无效令牌错误。知道我做错了吗?

3 个答案:

答案 0 :(得分:23)

您的问题在于wrap-defaults和site-defaults设置。 site-defaults默认配置添加了ant9forgery CSRF保护,任何不包含有效CSRF令牌的post请求都将被阻止。

有几种方法可以解决这个问题。

  1. 使用api-defaults而不是site-defaults。 api-defaults默认配置适用于您正在提供Web API的站点以及站点默认值中包含的CSRF保护,这适用于更传统的网站,其中发布请求是由之前已交付的表单生成的通过get请求并将csrf-token包含为隐藏字段。此解决方案的缺点是它还可能禁用您希望包含的其他中间件

  2. 在site-default配置中禁用csrf保护。这涉及将地图中的适当键值设置为假,即 eager_load

答案 1 :(得分:3)

请参阅此github example。特别是在底部:

  

ring-defaults默认包括POST请求的防伪(和   其他修改数据的人。)

如果你不想要这个,我认为你需要改变你对默认值的使用:

wrap-defaults routes site-defaults

如果您不想禁用它,则需要提交带有令牌的隐藏字段的表单,或者通过X-CSRF-TokenX-XSRF-Token将其传递到标题中。有关详细信息,请参阅环形中间件docs以获取环形防伪。

答案 2 :(得分:3)

在表单中添加隐藏字段,例如使用enlive-html:

char

或禁用它,不推荐,如:

(def app   (wrap-defaults app-routes(assoc-in site-defaults [:security:anti-forgery] false)))