Wednesday, August 5, 2015

CSRF-Token Global method for all ajax request

Rails is providing many clever methods to prevent the application from the security attacks.  In that CSRF token also one of them.

Read more about CSRF.

Rails will check the CSRF token in each request, and will determine whether the token is correct or not.

If you are using any form helper to create form tag, the helper by default it will put the CSRF token in the hidden field inside the form tag.  So by submitting the form automatically the token will go with the request.  The problem comes, when we are trying to send the request through JavaScript.

To solve that, We have to add the csrf_meta_tags in layout, like below

<html>
  <head>
    <%= csrf_meta_tags %>
  </head>

  <body>
    <!-- Your body content will go here.... -->
  </body>
</html>

This will add the CSRF token in the html pages meta tag.  We can use this token in JavaScript to send AJAX request like below

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

This line will take the CSRF token from the meta tag and will append to the Ajax request's header.

Lets say your application is having this kind of Ajax request around 1000 places, you have to repeat this piece of code each time.  To avoid this we can write this code globally like below.

jQuery:

$(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'))
  }
Add the above script in your JavaScript file, then by default all your Ajax request will contain the CSRF token in the requests' header, and it is designed in such a way that you can show / hide loader, spinner or common error / success message for Ajax response.