user4855927
user4855927

Reputation:

How do rails authenticity tokens work? Further clarification needed

I was reading this stackoverflow comment which describes how rails authenticity tokens work: Understanding the Rails Authenticity Token

and the highest rated response begins with this:

"When the user views a form to create, update, or destroy a resource, the Rails app creates a random authenticity_token, stores this token in the session, and places it in a hidden field in the form. When the user submits the form, Rails looks for the authenticity_token, compares it to the one stored in the session, and if they match the request is allowed to continue."

This makes sense to me as an abstract concept but I wanted to understand how this works in a concrete sense, I wanted to see exactly how this happens so I am crystal clear about how this works, so I created a new rails app and scaffolded a User with just one field name then I dropped a binding.pry in Users#create right up top inside the action, which should happen directly after the user submits the form. The pry session began right after I added a new user name, hit submit and it moves to create...So I inspected the source of my application in my web browser to find that the csrf-token content value in my rails generated csrf meta tags do not match the hidden authenticity token value within my form and neither one matches the value I get if, during the same pry session, I examine the session.to_hash property and inspect the "_csrf_token" value.

I then tried setting up a pry in the Users#new action and the Users#create action and noted the "_csrf_token" value on the session and compared it to the values of the form fields and meta tags once I quit and my app moved to the pry in the Users#create action but nothing matched. It seems like none of these three values match at all.

Yet protect_from_forgery with: :exception is set in my application controller and from what I read in the top rated response I was expecting to see matching values...somewhere. It seems like nothing matches. So I currently have no concept of what rails is matching what to in order to allow for the form to proceed and the data to be saved.

The author of the top rated response also says that an authenticity_token is stored on the session but all I see is a _csrf_token (are these the same?) and a session_id and, as I said, they don't match anything. I see no match whatsoever.

If rails is matching something to the value in my form field, it doesn't seem to be the value of the '_csrf_token' unless its converting it to something else behind the scenes and then matching that value to the value in the hidden form field or something. I don't feel like I understand what is going on.

Upvotes: 2

Views: 337

Answers (1)

Richard Peck
Richard Peck

Reputation: 76784

Rails is built on top of the HTTP protocol.

enter image description here

HTTP is stateless, which means that each request has to be treated as unique (all the supporting data has to be built each time).

To do this, Rails has the session, which is a series of "cookies" stored on the browser's system:

HTTP is a stateless protocol. Sessions make it stateful.

These sessions are used to keep small snippets of data which are used by Rails to rebuild your user's "environment" with each request. Devise stores user_id in the session, and Rails keeps a ton of other data in there, too.

--

So as opposed to - for example - a game, where you have a continual flow of data via a stateful protocol such as TCP (once the connection is established, it stays established), Rails basically reconnects with each new request.

Part of this process is form submission.

To prevent problems arising from this (IE bots/spammers sending millions of requests), Rails uses CSRF to "match" the authenticity token in the user's session with the one displayed on the web page.

This basically says that the user submitting the form is the one who originally made the request, not some bot which got the from through a proxy or some shady software.

You end up with the following:

enter image description here

enter image description here

Upvotes: 0

Related Questions