Another way of introducing the anti-forgery token is to bind it to a javascript variable.
[:script "var antiForgeryToken = " (pr-str *anti-forgery-token*)] In ClojureScript, you can then access the token with js/antiForgeryToken. The Ring-Defaults library exists to provide a way of applying common middleware in the right order. Certain middleware depend on other middleware, so the order in which they're applied to a handler is important. For instance, wrap-anti-forgery depends on wrap-session. The wrap-defaults middleware just takes a map of options, and then uses this to decide which middleware to apply. The order in which the middleware is applied it handled for you. It also provides some default maps of options that you can adapt. Regarding *anti-forgery-token* being unbound, this is because it's a binding. If a var has "earmuffs", like *foo*, it indicates it's designed to be used with the binding macro. For example: (declare *foo*) ;; like def, but doesn't have a value yet (defn print-foo [] (println *foo*)) (binding [*foo* "Hello World"] (print-foo)) ;; prints "Hello World" The value of *foo* is passed into print-foo without needing to be passed as an argument. Any function inside the binding can access *foo*. This is useful property for *anti-forgery-token* to have, because it means we don't need to manually pass the token to the function that returns the response. The anti-forgery token is randomly generated for each request you make, then added to both the session (automatically) and the page you return as a response (manually). The idea is that this ensures two things: 1. The user is logged in 2. The user has come from a page you control You mention that Clojure rewards investment into its fundamental building blocks. That's very true, and at this point unfortunately a little unavoidable! Fortunately the building blocks are fairly simple IMO, and once you understand them you should make more rapid progress. Also, don't be afraid of looking at source code. Clojure libraries are frequently both small and "flat". You don't get the dense hierarchies of class structures that tend to occur in OOP. When I was using Ruby and Python it was extremely rare for me to look at the source code of libraries, for exactly the reason you mention. But in Clojure I almost always look at the source code of any library I use. Some are still complex, but most I find to be understandable even if I'm just skimming. Clojure web development is currently made up of small, specialised libraries. I think overall it's easier for me to understand what's going on in Clojure as opposed to something like Ruby. On the other hand, because the pieces are isolated, tasks like CSRF-protection that require coordination between the server and the client become difficult. Arachne <http://arachne-framework.org/> is a promising attempt to make a web framework for Clojure. Another project that's slowly heading in that direction is my own Duct <https://github.com/duct-framework/duct> project, though by smaller increments. I know Luke expects an alpha of Arachne out by the end of January, and the next version of Duct should be out at around the same time. - James On 23 December 2016 at 16:49, Seth Archambault <sethvi...@gmail.com> wrote: > Okay, armed with the new clarity, I felt embolden to tackle this once > more. Here's the next steps for those trying to tack CSRF protection onto a > Reagent project created with lein new reagent. > > In handler.clj - you'll add the ring.middleware.anti-forgery and refer to > *anti-forgery-token* > > (ns myapp.handler > (:require > [ring.middleware.anti-forgery :refer [*anti-forgery-token*]])) > > > Then, lower down in your code you'll have something like this: > > (html5 > [:head > [:meta {:csrf-token *anti-forgery-token*}] > > > This will create a token for you. > > Now I haven't gone the rest of the distance with this problem so I can't > say that it's all downhill from here, it's possible I'm messing up and > re-generating a token that won't match what's already matched in the > session. Let me know if that's what I'm doing :( > > But the next thing I would do, is in /cljs/myapp/core.cljs - I would find > a way to pull in this token from the meta tag (maybe by using vanilla > javascript) and then add it to my post commands. > > A couple things that confused me: > > It's not obvious that you have to add ring.middleware.anti-forgery to > handler.clj, because in the examples in the documentation we're pulling > that in so we can do "wrap-anti-forgery" in our middleware.clj. However, > this is done automatically using ring.middleware.defaults, in the > middleware.clj file, so it looks like ring.middleware.anti-forgery > doesn't need to be anywhere. > > However, without ring.middleware.anti-forgery, it seems > *anti-forgery-token* isn't bound.. once you require that, that it exists! > > Let me know if my assumptions are wrong on this - it's possible I'm going > down the wrong direction and that *anti-forgery-token* is actually stored > in the session somewhere, but I have no idea how to access the session at > this point.. That sounds like a whole nother bag of worms. > > *Epilogue* > > The turning point for me was realizing that the ring-defaults file is > ridiculously easy to comprehend on Github. I'm so used to php projects > where inspecting classes is basically impossible - in order to understand > one thing, you need to understand 12 other things, which in turn require an > understanding of 3 other things etc. To open up defaults.cli and see that > site-defaults is just a simple map, literally made me sigh in relief :p > > I'm beginning to grasp the structure of packages of namespaces, which > makes seeing into the code easier. It strikes me Clojure is a system which > dramatically rewards investment into it's fundamental building blocks. I > feel like I have a lot to learn, but it's all worth learning. Thanks! > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.