7

I copied some old code that was working in compojure 1.1.18 and other old libs, but using the latest versions I can't get it to work.

Here's my minimal example code copied from the minimal example here to demonstrate that with latest ring and compojure libraries, I get an error when I send an http POST, even with the header set.

lein ring server to start it, then do

curl -X GET --cookie-jar cookies "http://localhost:3000/" which results in something like this:

{"csrf-token":"7JnNbzx8BNG/kAeH4bz1jDdGc7zPC4TddDyiyPGX3jmpVilhyXJ7AOjfJgeQllGthFeVS/rgG4GpkUaF"}

But when I do this

curl -X POST -v --cookie cookies -F "email=someone@gmail.com" --header "X-CSRF-Token: 7JnNbzx8BNG/kAeH4bz1jDdGc7zPC4TddDyiyPGX3jmpVilhyXJ7AOjfJgeQllGthFeVS/rgG4GpkUaF" http://localhost:3000/send

I get <h1>Invalid anti-forgery token</h1>

Am I doing something wrong?

The code I borrowed was intended to answer this question.

Community
  • 1
  • 1
sventechie
  • 1,859
  • 1
  • 22
  • 51
  • shot in the dark but does escaping the forward slashes (in the token) using backslashes make any difference? – user2524973 May 11 '15 at 17:25
  • Thanks! James Reeves / weavejester, the author of compojure and [maintainer of ring anti-forgery told me that the new `wrap-defaults` and `site-defaults` in the `ring-defaults` package](https://github.com/ring-clojure/ring-anti-forgery/issues/10) that replaces the deprecated compojure `handler` namespace automatically require CSRF tokens for HTTP `POST` et al. So my code generates the token twice and I verify against the wrong one. I'm working on a fix... – sventechie May 11 '15 at 19:53

1 Answers1

5

The problem was that ring-defaults (which replaces the compojure.handler namespace in compojure >= 1.2) automatically uses ring anti-forgery in the usual mode of use:

(defroutes app-routes
  (GET "/" [] (generate-string {:csrf-token
                                *anti-forgery-token*}))
  (POST "/send" [email] "ok")
  (resources "/")
  (not-found "Not Found"))

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

So two anti-forgery tokens were being generated and the GET request provided the invalid one. Removing the wrap-anti-forgery line fixed the problem.

sventechie
  • 1,859
  • 1
  • 22
  • 51