My answer borrows heavily from both @Jimbo and @Sija, however I'm using the devise/angularjs convention suggested at Rails CSRF Protection + Angular.js: protect_from_forgery makes me to log out on POST, and elaborated a little on my blog when I originally did this. This has a method on the application controller to set cookies for csrf:
after_filter :set_csrf_cookie_for_ng
def set_csrf_cookie_for_ng
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
So I'm using @Sija's format, but using the code from that earlier SO solution, giving me:
class SessionsController < Devise::SessionsController
after_filter :set_csrf_headers, only: [:create, :destroy]
protected
def set_csrf_headers
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
end
end
For completeness, since it took me a couple of minutes to work it out, I also note the need to modify your config/routes.rb to declare that you've overridden the sessions controller. Something like:
devise_for :users, :controllers => {sessions: 'sessions'}
This was also part of a large CSRF cleanup that I've done on my application, which might be interesting to others. The blog post is here, the other changes include:
Rescuing from ActionController::InvalidAuthenticityToken, which means that if things get out of synch the application will fix itself, rather than the user needing to clear cookies. As things stand in rails I think your application controller will be defaulted with:
protect_from_forgery with: :exception
In that situation, you then need:
rescue_from ActionController::InvalidAuthenticityToken do |exception|
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
render :error => 'invalid token', {:status => :unprocessable_entity}
end
I've also had some grief with race conditions and some interactions with the timeoutable module in Devise, which I've commented on further in the blog post - in short you should consider using the active_record_store rather than cookie_store, and be careful about issuing parallel requests near to sign_in and sign_out actions.