rails - "WARNING: Can't verify CSRF token authenticity" for json devise requests

user1027503 picture user1027503 · Feb 20, 2012 · Viewed 85.8k times · Source

How can I retrieve the CSRF token to pass with a JSON request?

I know that for security reasons Rails is checking the CSRF token on all the request types (including JSON/XML).

I could put in my controller skip_before_filter :verify_authenticity_token, but I would lose the CRSF protection (not advisable :-) ).

This similar (still not accepted) answer suggests to

Retrieve the token with <%= form_authenticity_token %>

The question is how? Do I need to do a first call to any of my pages to retrieve the token and then do my real authentication with Devise? Or it is an information one-off that I can get from my server and then use consistently (until I manually change it on the server itself)?

Answer

Ryan Crews picture Ryan Crews · Apr 7, 2012

EDIT:

In Rails 4 I now use what @genkilabs suggests in the comment below:

protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }

Which, instead of completely turning off the built in security, kills off any session that might exist when something hits the server without the CSRF token.


skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }

This would turn off the CSRF check for json posts/puts that have properly been marked as such.

For example, in iOS setting the following to your NSURLRequest where "parameters" are your parameters:


[request setHTTPMethod:@"POST"];

[request setValue:@"application/json" 
       forHTTPHeaderField:@"content-type"];

[request setValue:@"application/json" 
       forHTTPHeaderField:@"accept"];

[request setHTTPBody:[NSData dataWithBytes:[parameters UTF8String] 
                                            length:[parameters length]]];