Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is the ring anti-forgery token inserted?

I'm trying to understand when the ring anti-forgery token is generated or inserted in an HTML page. I'm using Compojure / ring / hiccup but I take it my question is really about ring. I don't have any problem per se: I just want to know when and how the anti-forgery token is "injected".

The anti-forgery-field function from ring.util.anti-forgery is implemented like this:

(html (hidden-field "__anti-forgery-token" *anti-forgery-token*)

If I call this function at a REPL I get:

REPL>  (println (anti-forgery-field))
<input id="__anti-forgery-token" name="__anti-forgery-token" type="hidden" value="Unbound: #&apos;ring.middleware.anti-forgery/*anti-forgery-token*" />

Still at the REPL, if I try to get this var I get the same "unbound" variable:

> ring.middleware.anti-forgery/*anti-forgery-token*
=> #object[clojure.lang.Var$Unbound 0x1eae055 "Unbound: #'ring.middleware.anti-forgery/*anti-forgery-token*"]

What I don't understand is what that "Unbound" value is nor when it is transformed (by ring?) into an actual token delivered. And I especially don't understand how several users connecting to the website do get, each, a different token (per session).

Is that variable always "unbound"? When/how does it become "bound" (if it does?)?

Also, if I've got the ring session ID (say "ring-session=310678be-9ef6-41a7-a12a-b2417de4a79f"), how can I see, at the Clojure REPL (on the server side), the corresponding anti-forgery token's value?

like image 615
Cedric Martin Avatar asked Apr 07 '17 18:04

Cedric Martin


1 Answers

It is bound only in the context (dynamic environment, the current stack, if you will) of the individual request. Think of it as a thread-local variable/binding. You are not in the context of a request while looking at your application state from a REPL.

It must be this way, because it has to be a different value for each user. You'd simulate similar behaviour through an explicit lookup call, if you were working in an environment that does not allow this kind of control of the dynamic environment.

The binding to the right session value is established in the middleware during the request, currently here:

https://github.com/weavejester/ring-anti-forgery/blob/master/src/ring/middleware/anti_forgery.clj#L67

(binding [*anti-forgery-token* (session-token request)]
  ;; ...
  )
like image 73
Svante Avatar answered Oct 05 '22 21:10

Svante