Question

Understanding the Rails Authenticity Token in Ruby on Rails

rubyruby-on-railsauthenticity-token

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, and DELETE
  • 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.

Take Quiz

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.
  • GET requests 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:

  1. A user visits the page.
  2. Rails renders the form on the server.
  3. Rails inserts a hidden authenticity_token field into the HTML.
  4. The browser displays the form to the user.
  5. The user enters a title and clicks Create.
  6. The browser submits the form data, including the hidden token.
  7. Rails receives the request and checks the token.
  8. If the token matches what Rails expects for that session, the request continues.
  9. 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 DELETE or PATCH

    • 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.

Take Quiz

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_with
  • form_for in older apps
  • form_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:

  • GET reads data
  • POST creates
  • PATCH or PUT updates
  • DELETE removes

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.

ConceptPurposeSame as authenticity token?Notes
Session cookieIdentifies the user's sessionNoSent automatically by the browser
Authenticity tokenProtects against CSRFYesVerifies request origin from trusted app pages
PasswordAuthenticates the userNoUsed at login time
API token / bearer tokenAuthenticates API clientsNoCommon in stateless APIs
JWTCarries authentication/claims dataNoOften 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

ApproachIncludes token automatically?Best for beginners?
form_withYesYes
form_tagYesYes
Raw HTML <form>No, not by defaultUsually no

Browser session app vs API-only app

App typeCSRF concernTypical approach
Standard Rails app with cookiesHighKeep authenticity token protection enabled
API-only app with bearer tokensDifferent threat modelOften no CSRF token, depending on auth strategy

The key difference is whether the browser automatically sends credentials like cookies.

Take Quiz

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:
    • POST
    • PATCH
    • PUT
    • DELETE
  • 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_tags in 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.

Take Quiz

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

  1. Create a page with a form for a post title.
  2. Submit one request using a normal Rails form helper.
  3. Add a button that sends a POST request with JavaScript.
  4. Include the CSRF token in the JavaScript request.
  5. Save the post and display a success response.
Take Quiz

Keep learning

Related questions

View more