3

I need to make an HTTP POST request from outside the browser, but the Rails back-end is not accepting the authentication (error 401). I know I need to pass a CSRF token in such cases, but it's not working.

When I make the request through a form on a browser, it works as expected, but when I try to simulate an identical request (in terms of headers and cookies) from outside the browser (using curl, for example), the authentication doesn't work.

Two small changes allowed me success without a browser: (1) turning off protect_from_forgery, which validates the CSRF or (2) using GET instead of POST for the request. In both cases, passing the cookie is enough. That means the problem is definitely related to CSRF stuff.

So, my question is: how can I make a CSRF-protected HTTP POST to a Rails server without using a browser?

To clarify, the process is broken in three steps:

  1. Login: returns a cookie to identify the session;

  2. New: a GET request that returns the CSRF token to be used later (uses the cookie);

  3. Create: a POST request that submits the information I want to create (uses both the session cookie and the CSRF token).

The only step which fails is the third one.

André Lima
  • 651
  • 1
  • 6
  • 11
  • If you have another form of authentication, such as API keys, then you can use **skip_before_filter :verify_authenticity_token** on your controller. Only use this if you have an authentication method in place or if you are using web hooks from an external service. – Gazler Jun 02 '11 at 19:18

1 Answers1

2

Assuming your CSRF token is cookie-based, then the program you use to make your requests needs to track cookies. Check out the --cookie-jar option in curl.

tylerl
  • 30,197
  • 13
  • 80
  • 113
  • Thank You, @tylerl! I was using the cookie returned by step 1 in the third step. Keeping the cookie returned by step 2 and using it in step 3 solved my problem! There is no mention to CSRF in the content of the second cookie, but it seems that since the session changed, the correct one should be used. – André Lima Jun 02 '11 at 19:34