In working through AngularJS and Rails integration, one of the matters that comes up frequently is CSRF protection. This is an important security measure, and this post points to the solution that I found on stackoverflow, and provides the code snippet that I implemented, and how I verified that it seems to be working. This content has also been included in the Rails 3 and AngularJS tutorial, available from the tutorials menu above, and the Rails 4 and AngularJS tutorial, also available from the tutorial menu above, or this specific post within that tutorial.
There is also a more thorough treatment of this content in another post, here (described in more detail at the bottom of this post).
An alternative approach is through a project that introduces CSRF into rails and angular, ng-rails-csrf. My feel was that it integrated rails and angular too closely, I wasn’t keen to have my angular living in my rails asset pipeline.
The code that we end up with in application_controller.rb is as follows:
class ApplicationController < ActionController::Base protect_from_forgery after_filter :set_csrf_cookie_for_ng def set_csrf_cookie_for_ng cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery? end protected def verified_request? super || form_authenticity_token == request.headers['X_XSRF_TOKEN'] end end
If you’re on rails 4, you the verified_request? line needs hyphens, not underscores:
super || form_authenticity_token == request.headers['X-XSRF-TOKEN']
We can check if this is working in the following way. In our sample app, before this code is implemented, we can go to the club or team entity, and press the delete button. We’ll see on our rails server console a message
WARNING: Can't verify CSRF token authenticity. In production this transaction would actually reject, in dev and test CSRF protection is turned down to only a warning, as the rspec test cases have difficulty providing the tokens correctly. Our aim is for this message to go away.
Implement the code snippet into your application_controller, and restart your rails server (I’m not 100% you have to restart, but I think you do). Then refresh your browser, and look at the network traffic monitor (if you’re on Chrome) to see that the get transaction now sets an XSRF-TOKEN cookie. Hit the delete button, and you’ll see that your rails server no longer complains about CSRF token authenticity.
Since I wrote this there have been some extensions.
1. There is now a gem available that is based on this discussion above https://github.com/jsanders/angular_rails_csrf, provided by jsanders.
2. I’ve written a more elaborate post, dealing with issues relating to Devise, multithreading, and the newer Rails 4 behaviour.