Question
Understanding the Rails Authenticity Token in Ruby on Rails
Question
In Ruby on Rails, what is the authenticity token, what is it used for, and why does Rails include it in forms and requests?
Short Answer
By the end of this page, you will understand what the Rails authenticity token is, how it helps prevent CSRF attacks, where it appears in forms and requests, and how developers work with it in everyday Rails applications.
Concept
The authenticity token in Rails is a security value used to help protect your application from Cross-Site Request Forgery (CSRF) attacks.
A CSRF attack happens when a user is logged into your Rails app, and a malicious site tricks their browser into sending a request to your app without the user's intent. Because the browser may automatically include session cookies, your app could mistakenly treat that request as legitimate.
Rails defends against this by adding a unique token to forms and checking that token when the form is submitted. If the token is missing or invalid, Rails can reject the request.
Why this matters
Without CSRF protection, dangerous actions could be triggered silently, such as:
- changing an email address
- updating account settings
- deleting data
- submitting payments
- creating or modifying records
How Rails uses it
When CSRF protection is enabled, Rails:
- generates an authenticity token for the user's session
- embeds it in non-GET forms
- verifies the token on incoming state-changing requests such as
POST,PATCH,PUT, andDELETE - rejects requests that fail verification
In Rails controllers, this is typically handled automatically through built-in CSRF protection.
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
end
This tells Rails to raise an exception if a request fails CSRF verification.
Important idea
The authenticity token is not for user authentication like a password or login token. It is specifically for proving that a form submission came from a page your Rails app generated for that user.
Mental Model
Think of the authenticity token like a secret stamp that your app places on every official form.
- Your Rails app creates the form.
- It adds a hidden security stamp.
- When the form comes back, Rails checks for that stamp.
- If the stamp is missing or wrong, Rails assumes the request may be forged.
A malicious website can try to send a request to your app, but it usually cannot read and reuse the correct secret stamp from your Rails page. That is what makes the token useful.
So the mental model is:
- session cookie = identifies the logged-in user
- authenticity token = proves the request came from a trusted Rails-generated form
You usually need both for a safe state-changing request.
Syntax and Examples
Rails usually adds the authenticity token automatically in forms created with Rails helpers.
Example: form_with
<%= form_with model: @post do |form| %>
<%= form.text_field :title %>
<%= form.submit "Save" %>
<% end %>
Rails generates HTML that includes a hidden field similar to this:
<input type="hidden" name="authenticity_token" value="...token here...">
Example: form_tag
<%= form_tag posts_path do %>
<%= text_field_tag :title %>
<%= submit_tag "Create Post" %>
<% end %>
This also includes an authenticity token automatically.
Example: token in page markup for JavaScript
Rails often includes a CSRF token in a meta tag so JavaScript-based requests can send it too:
<%= csrf_meta_tags %>
This renders tags like:
<meta name="csrf-param" content="authenticity_token">
<meta name="csrf-token" content="abc123...">
Example: sending the token with JavaScript
const token = document.querySelector('meta[name="csrf-token"]').content;
fetch('/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': token
},
body: JSON.stringify({ title: 'Hello' })
});
What to remember
- Rails form helpers include the token automatically.
GETrequests usually do not need CSRF verification because they should not change server data.- Custom JavaScript requests that change data usually need to send the token manually unless a Rails tool does it for you.
Step by Step Execution
Consider this Rails form:
<%= form_with url: posts_path, method: :post do |form| %>
<%= form.text_field :title %>
<%= form.submit "Create" %>
<% end %>
Here is what happens step by step:
- A user visits the page.
- Rails renders the form on the server.
- Rails inserts a hidden
authenticity_tokenfield into the HTML. - The browser displays the form to the user.
- The user enters a title and clicks Create.
- The browser submits the form data, including the hidden token.
- Rails receives the request and checks the token.
- If the token matches what Rails expects for that session, the request continues.
- If the token is missing or invalid, Rails rejects the request.
Simplified submitted form data
title=My+Post
authenticity_token=abc123...
If the token is valid
The controller action runs normally:
class PostsController < ApplicationController
def create
@post = Post.create!(title: params[:title])
redirect_to @post
end
end
If the token is invalid
Rails may raise an error such as ActionController::InvalidAuthenticityToken, depending on configuration.
That means the request looked suspicious or was missing required CSRF protection.
Real World Use Cases
Authenticity tokens are used any time a Rails app accepts requests that change data.
Common examples
-
Login and logout forms
- Prevent forged requests that sign users out or attempt unwanted actions.
-
Account settings forms
- Protect updates to email, password, profile, or notification settings.
-
Admin dashboards
- Prevent attackers from tricking an admin into deleting users or changing permissions.
-
Shopping carts and checkout flows
- Protect quantity changes, address updates, and order submission.
-
AJAX requests in single-page features
- JavaScript requests that create, update, or delete data usually send the CSRF token in a header.
-
Buttons using
DELETEorPATCH- Rails links and buttons that act like non-GET requests rely on CSRF protection too.
In short, if a request changes application state, CSRF protection is relevant.
Real Codebase Usage
In real Rails codebases, developers usually do not manually manage authenticity tokens for standard forms. Rails handles most of it.
Common patterns
1. Rely on Rails form helpers
Developers use helpers like:
form_withform_forin older appsform_tag
These helpers automatically include the token.
2. Keep CSRF protection enabled in ApplicationController
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
end
This is the default pattern for browser-based Rails apps.
3. Send the token in custom JavaScript requests
When using fetch, axios, or custom front-end code, developers read the token from csrf_meta_tags and send it as a request header.
4. Use guardrails around APIs
Pure JSON APIs that do not rely on browser sessions often use token-based authentication instead of session cookies, and may disable CSRF protection for those endpoints if appropriate. This should be done carefully and intentionally.
5. Handle invalid tokens gracefully
Some apps rescue token errors to redirect users or show a helpful message:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
rescue_from ActionController::InvalidAuthenticityToken do
redirect_to new_session_path, alert: "Your session expired. Please sign in again."
end
end
This pattern is common when expired sessions are expected.
6. Use early validation of request safety
CSRF checks act like an early guard clause for incoming requests. Rails verifies the request before your controller logic performs database changes.
Common Mistakes
Beginners often misunderstand what the authenticity token does.
1. Confusing it with authentication
Mistake: Thinking the token logs the user in or proves their identity.
The authenticity token does not replace:
- passwords
- sessions
- API tokens
- JWTs
It only helps prove that a request came from a trusted page in your app.
2. Removing the token from custom forms
Broken example:
<form action="/posts" method="post">
<input type="text" name="title">
<button type="submit">Create</button>
</form>
If this raw HTML is used in Rails without the token, the request may fail CSRF verification.
Use Rails helpers or add the token properly.
3. Forgetting the token in JavaScript requests
Broken example:
fetch('/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ title: 'Hello' })
});
This may fail because the X-CSRF-Token header is missing.
Fixed version:
const token = document.querySelector('meta[name="csrf-token"]').content;
fetch('/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': token
},
body: JSON.stringify({ title: 'Hello' })
});
4. Disabling CSRF protection without understanding the risk
Some beginners do this to “fix” token errors:
skip_before_action :verify_authenticity_token
That can remove an important security layer. Only disable verification for specific endpoints when you fully understand why it is safe.
5. Expecting GET requests to use authenticity tokens
CSRF protection mainly matters for requests that change data. In normal REST design:
GETreads dataPOSTcreatesPATCHorPUTupdatesDELETEremoves
If your GET request changes data, that design itself is a problem.
6. Forgetting csrf_meta_tags
If your JavaScript relies on reading the CSRF token from the page, but your layout does not include:
<%= csrf_meta_tags %>
then your JS may not be able to send the token.
Comparisons
Here are some useful comparisons.
| Concept | Purpose | Same as authenticity token? | Notes |
|---|---|---|---|
| Session cookie | Identifies the user's session | No | Sent automatically by the browser |
| Authenticity token | Protects against CSRF | Yes | Verifies request origin from trusted app pages |
| Password | Authenticates the user | No | Used at login time |
| API token / bearer token | Authenticates API clients | No | Common in stateless APIs |
| JWT | Carries authentication/claims data | No | Often used in APIs and SPAs |
Authenticity token vs session cookie
- Session cookie: tells Rails which logged-in user is making the request.
- Authenticity token: helps prove the request was intentionally submitted from your Rails page.
A browser can automatically send cookies to your site, which is why cookies alone are not enough to prevent CSRF.
Rails form helpers vs raw HTML forms
| Approach | Includes token automatically? | Best for beginners? |
|---|---|---|
form_with | Yes | Yes |
form_tag | Yes | Yes |
Raw HTML <form> | No, not by default | Usually no |
Browser session app vs API-only app
| App type | CSRF concern | Typical approach |
|---|---|---|
| Standard Rails app with cookies | High | Keep authenticity token protection enabled |
| API-only app with bearer tokens | Different threat model | Often no CSRF token, depending on auth strategy |
The key difference is whether the browser automatically sends credentials like cookies.
Cheat Sheet
- Authenticity token: Rails security token used to prevent CSRF attacks.
- Main job: verify that a state-changing request came from a trusted page generated by your app.
- Usually included in:
POSTPATCHPUTDELETE
- Usually not needed for:
GET
Common Rails pieces
protect_from_forgery with: :exception
<%= form_with model: @post do |form| %>
...
<% end %>
<%= csrf_meta_tags %>
JavaScript header
'X-CSRF-Token': token
Hidden form field
<input type="hidden" name="authenticity_token" value="...">
Error you may see
ActionController::InvalidAuthenticityToken
Rules of thumb
- Use Rails form helpers when possible.
- Keep CSRF protection enabled for session-based apps.
- Include
csrf_meta_tagsin your layout if JavaScript sends requests. - Do not disable verification just to hide errors.
- The token is not a login credential.
FAQ
What is the authenticity token in Rails?
It is a security token Rails uses to help prevent CSRF attacks on state-changing requests.
Why does Rails include an authenticity token in forms?
Rails includes it so the server can verify that the submitted form came from your application, not from a malicious external site.
Is the authenticity token the same as a session cookie?
No. A session cookie identifies the user session, while the authenticity token helps verify the request source.
Do all Rails forms need an authenticity token?
Forms that change data usually do. Rails form helpers add it automatically for those cases.
Why do I get InvalidAuthenticityToken in Rails?
Usually because the request is missing the token, the token is invalid, the session expired, or a custom JavaScript request did not send the CSRF header.
Do GET requests need an authenticity token?
Normally no, because GET requests should only read data and not change server state.
How do I send the authenticity token with fetch in Rails?
Read it from the csrf-token meta tag and send it in the X-CSRF-Token request header.
Can I disable authenticity token checking in Rails?
Yes, but only when you understand the security implications. Disabling it carelessly can expose your app to CSRF attacks.
Mini Project
Description
Build a small Rails page that creates posts using a standard Rails form and a JavaScript request. This project demonstrates where the authenticity token appears and how Rails uses it for both regular form submissions and custom fetch requests.
Goal
Create a Rails feature that safely submits a new post through both a normal form and a JavaScript POST request using the authenticity token.
Requirements
- Create a page with a form for a post title.
- Submit one request using a normal Rails form helper.
- Add a button that sends a POST request with JavaScript.
- Include the CSRF token in the JavaScript request.
- Save the post and display a success response.
Keep learning
Related questions
Add a Default Value to an Existing Column in a Rails Migration
Learn how to add or change a default value on an existing database column using Rails Active Record migrations safely.
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.