[ruby-on-rails] WARNING: Can't verify CSRF token authenticity rails

I am sending data from view to controller with AJAXand I got this error:

WARNING: Can't verify CSRF token authenticity

I think I have to send this token with data.

Does anyone know how can I do this ?

Edit: My solution

I did this by putting the following code inside the AJAX post:

headers: {
  'X-Transaction': 'POST Example',
  'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},

This question is related to ruby-on-rails jquery csrf

The answer is


You can write it globally like below.

Normal JS:

$(function(){

    $('#loader').hide()
    $(document).ajaxStart(function() {
        $('#loader').show();
    })
    $(document).ajaxError(function() {
        alert("Something went wrong...")
        $('#loader').hide();
    })
    $(document).ajaxStop(function() {
        $('#loader').hide();
    });
    $.ajaxSetup({
        beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}
    });
});

Coffee Script:

  $('#loader').hide()
  $(document).ajaxStart ->
    $('#loader').show()

  $(document).ajaxError ->
    alert("Something went wrong...")
    $('#loader').hide()

  $(document).ajaxStop ->
    $('#loader').hide()

  $.ajaxSetup {
    beforeSend: (xhr) ->
      xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
  }

If you are not using jQuery and using something like fetch API for requests you can use the following to get the csrf-token:

document.querySelector('meta[name="csrf-token"]').getAttribute('content')

fetch('/users', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')},
    credentials: 'same-origin',
    body: JSON.stringify( { id: 1, name: 'some user' } )
    })
    .then(function(data) {
      console.log('request succeeded with JSON response', data)
    }).catch(function(error) {
      console.log('request failed', error)
    })

Use jquery.csrf (https://github.com/swordray/jquery.csrf).

  • Rails 5.1 or later

    $ yarn add jquery.csrf
    
    //= require jquery.csrf
    
  • Rails 5.0 or before

    source 'https://rails-assets.org' do
      gem 'rails-assets-jquery.csrf'
    end
    
    //= require jquery.csrf
    
  • Source code

    (function($) {
      $(document).ajaxSend(function(e, xhr, options) {
        var token = $('meta[name="csrf-token"]').attr('content');
        if (token) xhr.setRequestHeader('X-CSRF-Token', token);
      });
    })(jQuery);
    


if someone needs help related with Uploadify and Rails 3.2 (like me when I googled this post), this sample app may be helpful: https://github.com/n0ne/Uploadify-Carrierwave-Rails-3.2.3/blob/master/app/views/pictures/index.html.erb

also check the controller solution in this app


I'm using Rails 4.2.4 and couldn't work out why I was getting:

Can't verify CSRF token authenticity

I have in the layout:

<%= csrf_meta_tags %>

In the controller:

protect_from_forgery with: :exception

Invoking tcpdump -A -s 999 -i lo port 3000 was showing the header being set ( despite not needing to set the headers with ajaxSetup - it was done already):

X-CSRF-Token: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
DNT: 1
Content-Length: 125
authenticity_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

In the end it was failing because I had cookies switched off. CSRF doesn't work without cookies being enabled, so this is another possible cause if you're seeing this error.


Indeed simplest way. Don't bother with changing the headers.

Make sure you have:

<%= csrf_meta_tag %> in your layouts/application.html.erb

Just do a hidden input field like so:

<input name="authenticity_token" 
               type="hidden" 
               value="<%= form_authenticity_token %>"/>

Or if you want a jQuery ajax post:

$.ajax({     
    type: 'POST',
    url: "<%= someregistration_path %>",
    data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" },                                                                                  
    error: function( xhr ){ 
      alert("ERROR ON SUBMIT");
    },
    success: function( data ){ 
      //data response can contain what we want here...
      console.log("SUCCESS, data="+data);
    }
});

Ugrading from an older app to rails 3.1, including the csrf meta tag is still not solving it. On the rubyonrails.org blog, they give some upgrade tips, and specifically this line of jquery which should go in the head section of your layout:

$(document).ajaxSend(function(e, xhr, options) {
 var token = $("meta[name='csrf-token']").attr("content");
  xhr.setRequestHeader("X-CSRF-Token", token);
});

taken from this blog post: http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails.

In my case, the session was being reset upon each ajax request. Adding the above code solved that issue.


I just thought I'd link this here as the article has most of the answer you're looking for and it's also very interesting

http://www.kalzumeus.com/2011/11/17/i-saw-an-extremely-subtle-bug-today-and-i-just-have-to-tell-someone/


  1. Make sure that you have <%= csrf_meta_tag %> in your layout
  2. Add a beforeSend to include the csrf-token in the ajax request to set the header. This is only required for post requests.

The code to read the csrf-token is available in the rails/jquery-ujs, so imho it is easiest to just use that, as follows:

$.ajax({
  url: url,
  method: 'post',
  beforeSend: $.rails.CSRFProtection,
  data: {
    // ...
  }
})

The best way to do this is actually just use <%= form_authenticity_token.to_s %> to print out the token directly in your rails code. You dont need to use javascript to search the dom for the csrf token as other posts mention. just add the headers option as below;

$.ajax({
  type: 'post',
  data: $(this).sortable('serialize'),
  headers: {
    'X-CSRF-Token': '<%= form_authenticity_token.to_s %>'
  },
  complete: function(request){},
  url: "<%= sort_widget_images_path(@widget) %>"
})

I struggled with this issue for days. Any GET call was working correctly, but all PUTs would generate a "Can't verify CSRF token authenticity" error. My website was working fine until I had added a SSL cert to nginx.

I finally stumbled on this missing line in my nginx settings:

location @puma { 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_redirect off;
    proxy_set_header X-Forwarded-Proto https;   # Needed to avoid 'WARNING: Can't verify CSRF token authenticity'
    proxy_pass http://puma; 
}

After adding the missing line "proxy_set_header X-Forwarded-Proto https;", all my CSRF token errors quit.

Hopefully this helps someone else who also is beating their head against a wall. haha


If you're using javascript with jQuery to generate the token in your form, this works:

<input name="authenticity_token" 
       type="hidden" 
       value="<%= $('meta[name=csrf-token]').attr('content') %>" />

Obviously, you need to have the <%= csrf_meta_tag %> in your Ruby layout.


The top voted answers here are correct but will not work if you are performing cross-domain requests because the session will not be available unless you explicitly tell jQuery to pass the session cookie. Here's how to do that:

$.ajax({ 
  url: url,
  type: 'POST',
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
  },
  xhrFields: {
    withCredentials: true
  }
});

If I remember correctly, you have to add the following code to your form, to get rid of this problem:

<%= token_tag(nil) %>

Don't forget the parameter.


For those of you that do need a non jQuery answer you can simple add the following:

xmlhttp.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));

A very simple example can be sen here:

xmlhttp.open("POST","example.html",true);
xmlhttp.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
xmlhttp.send();

oops..

I missed the following line in my application.js

//= require jquery_ujs

I replaced it and its working..

======= UPDATED =========

After 5 years, I am back with Same error, now I have brand new Rails 5.1.6, and I found this post again. Just like circle of life.

Now what was the issue is: Rails 5.1 removed support for jquery and jquery_ujs by default, and added

//= require rails-ujs in application.js

It does the following things:

  1. force confirmation dialogs for various actions;
  2. make non-GET requests from hyperlinks;
  3. make forms or hyperlinks submit data asynchronously with Ajax;
  4. have submit buttons become automatically disabled on form submit to prevent double-clicking. (from: https://github.com/rails/rails-ujs/tree/master)

But why is it not including the csrf token for ajax request? If anyone know about this in detail just comment me. I appreciate that.

Anyway I added the following in my custom js file to make it work (Thanks for other answers to help me reach this code):

$( document ).ready(function() {
  $.ajaxSetup({
    headers: {
      'X-CSRF-Token': Rails.csrfToken()
    }
  });
  ----
  ----
});

Examples related to ruby-on-rails

Embed ruby within URL : Middleman Blog Titlecase all entries into a form_for text field Where do I put a single filter that filters methods in two controllers in Rails Empty brackets '[]' appearing when using .where How to integrate Dart into a Rails app Rails 2.3.4 Persisting Model on Validation Failure How to fix "Your Ruby version is 2.3.0, but your Gemfile specified 2.2.5" while server starting Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? Rails: Can't verify CSRF token authenticity when making a POST request Uncaught ReferenceError: React is not defined

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to csrf

Post request in Laravel - Error - 419 Sorry, your session/ 419 your page has expired "The page has expired due to inactivity" - Laravel 5.5 Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN' Why is it common to put CSRF prevention tokens in cookies? include antiforgerytoken in ajax post ASP.NET MVC Cross Domain Form POSTing WARNING: Can't verify CSRF token authenticity rails How to properly add cross-site request forgery (CSRF) token using PHP What is a CSRF token? What is its importance and how does it work? Django CSRF check failing with an Ajax POST request