Thursday, July 18, 2013

AngularJS and XSRF/CSRF (Cross-Site Request Forgery)

When using AngularJS with a REST API, eventually, you will need to tinker with the XSRF/CSRF support, unless the backend already plays well with AngularJS. A Django + Django-Rest-Framework backend will send you a 403 (Forbidden) error during POST/PUT/DELETE requests, unless the CSRF settings are modified on one or both sides.

The flow works like this:
  1. The server generates a CSRF Token, which it sends to the client (typically through a setting in the cookie or hidden on a form page).
  2. The client records this token and sends it back to the server via an HTTP header.
  3. The server reads the HTTP header, compares it to the known CSRF Token for that session, then allows the request to go through if it matches.

A typical problem is that the backend's name for the cookie setting differs from what AngularJS is looking for, or the header that AngularJS sends back to the backend is not what it expects (or both).

By default, AngularJS looks for a cookie named "XSRF-TOKEN" and sets the header as "X-XSRF-TOKEN" as described here. Fortunately, it's easy to change this on the client side. I typically use a Django backend, and that sends a cookie named "csrftoken" to the browser. The 403 Forbidden error is due to the mismatch.

If using ng-boilerplate (highly recommended):
  1. Open up app.js.
  2. Inject $http and $cookies into the run method.
  3. Read the incoming CSRF token from the cookie or form ('csrftoken' or equivalent).
  4. Send it to the server during each request using the header that the backend is expecting (see the docs for your backend).

angular.module( '[your module name]',
    ... [some dependencies] ...
    'ngCookies',
    ... [other dependencies] ...
)


...

.run( function run( titleService, $http, $cookies ){

    titleService.setSuffix( '[title]' );

    // For CSRF token compatibility with Django

    $http.defaults.headers.post['X-CSRFToken'] = $cookies['csrftoken'];
})

...
;

Don't forget to add "'vendor/angular/angular-cookies.js'," under vendor_files in build.config.js for the build to pick up. Note that you will have to download the AngularJS files to get angular-cookies.js, since it currently does not come with the standard ng-boilerplate install. If you're not using ng-boilerplate, just be sure to add a reference to that JS file in your HTML.

This code will also work when using $resource, since that uses $http underneath. Preferably, we should set this during runtime in $resource itself, but this is not yet supported in the current stable AngularJS release (1.0.7), and I don't want to switch to an unstable version just to get this working.

I prefer this method than doing the modification on the server end, since when using multiple JS libraries, the header would need to be changed/added on the client end anyway. I also prefer transferring the token via the cookie instead of a form, since the latter could affect caching.

Thanks to this StackOverflow post, which provided the main clues on how to solve this in Angular.

14 comments:

  1. Thanks, this was very helpful.

    ReplyDelete
  2. If you are doing backend AJAX login which then sets the cookie, you'll need to update `$http.defaults.headers.post['X-CSRFToken']` with the updated cookie, otherwise you'll get CSRF failures from the backend for first time users that haven't reloaded/revisited the page ever.

    I did this by shamefully creating a global reference to `$cookiesProvider`:

    var cookiesProvider_ref = null;
    app.config( function($cookiesProvider) {
    cookiesProvider_ref = $cookiesProvider
    });

    I then use `cookiesProvider_ref` in my AJAX login's `success()` callback to set the `$http` csrf token header field again.

    ReplyDelete
  3. One thing that is seldom mentioned regarding this topic - if your front-end is on a different domain than your back-end, then your front-end will be unable to read the cookies that are sent from the back-end.

    ReplyDelete
  4. hi,for excellent videos on soapui
    refer
    http://soapui-tutorial.com/soapui-tutorial/introduction-to-webservices/

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. This blog will help me to learn angularjs very well. I really identify the all the tricks in this blog.Thanks for sharing.keep sharing more blogs.


    Angularjs Online Training

    ReplyDelete
  7. Thank you for sharing this information. I find this information is easy to understand and very useful. Thumbs up!


    Melbourne Hosting Services

    ReplyDelete
  8. Hi There


    Hip Hip Hooray! I was always told that slightly slow in the head, a slow learner. Not anymore! It’s like you have my back. I can’t tell you how much I’ve learnt here and how easily! Thank you for blessing me with this effortlessly ingestible digestible content
    How to create a MVC application with the combination of Angular 5.
    After creating what are the configurations that we have to make to build and run the application.
    Build means(single build should build the MVC + angular typescript code as well) .

    What are the steps to deploy this application.?

    Once again thanks for your tutorial.


    Gracias,
    Pranavi

    ReplyDelete
  9. Hi There,


    Hip Hip Hooray! I was always told that slightly slow in the head, a slow learner. Not anymore! It’s like you have my back. I can’t tell you how much I’ve learnt here and how easily! Thank you for blessing me with this effortlessly ingestible digestible content.

    Going from angularjs to angular2 does not clear out ui-view but vice-versa clear router-outlet. How to make it work as separate view.

    But great job man, do keep posted with the new updates.


    Many Thanks,
    John

    ReplyDelete
  10. Thank you.Well it was nice post and very helpful information on AngularJS5 Online Training Bangalore

    ReplyDelete
  11. Needed to compose you a very little word to thank you yet again regarding the nice suggestions you’ve contributed here. Those guidelines additionally worked to become a good way to recognize that other people online have the identical fervor like mine to grasp great deal more around this condition. We are providing AngularJs training in velachery.
    For more details: AngularJs training in Velachery

    ReplyDelete
  12. SVR Technologies provide Mulesoft Training with Mulesoft Video Tutorials, Live Project, Practicals - Realtime scenarios, CV, Interview and Certification Guidance.

    SVR Technologies MuleSoft training is designed according to the latest features of Mule 4.It will enable you to gain in-depth knowledge on concepts of Anypoint Studio Integration techniques, testing and debugging of Mule applications, deploying and managing the Mule applications on the cloud hub, dataweave transformations, etc. You will also get an opportunity to work on two real-time projects under the guidance of skilled trainers during this training.

    Enquire Now: +91 9885022027
    Enroll Now: https://bit.ly/2OCYVgv

    https://svrtechnologies.com/mulesoft-training/
    https://svrtechnologies.com/contact-us/

    ReplyDelete