我最近开始探索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"失败并出现无效令牌错误.知道我做错了什么吗?
您的问题在于wrap-defaults和site-defaults设置.site-defaults默认配置添加了ant9forgery CSRF保护,任何不包含有效CSRF令牌的post请求都将被阻止.
有几种方法可以解决这个问题
使用api-defaults而不是site-defaults.api-defaults默认配置适用于您正在提供Web API的站点以及站点默认值中包含的CSRF保护,这适用于更传统的网站,其中发布请求是由之前已交付的表单生成的通过get请求并将csrf-token包含为隐藏字段.此解决方案的缺点是它还可能禁用您希望包含的其他中间件
在site-default配置中禁用csrf保护.这涉及将地图中的适当键值设置为false,即
(wrap-defaults app-routes (assoc-in site-defaults [:security :anti-forgery] false))