0

I have a rails app with a POST url which creates some resources.I have a page with a form which takes in all the information and does an AJAX call to the POST url without authenticity token.

Am doing data["authenticity_token"] = "";, before doing the AJAX call.

Parameters logged on serverside are like below

{"utf8"=>"✓", "authenticity_token"=>"", "company_customer"=>{"name"=>"Anand"}}

The resources are created without any error(I have protect_from_forgery with: :exception in my ApplicationController).

But when I tried to call the same POST url from Postman, I get InvalidAuthenticityToken error.

  1. Why am I getting the error?
  2. How does the rails app verify the authenticity of the POST request in first case?

3 Answers3

0

In the first step i.e. from browser , you might be having some session id in the cookies but here not.

Also, if you were hitting by remote:true option, it will take the authenticity token from the page in the hidden field.

For more details , check your logs in both cases.

Chakreshwar Sharma
  • 2,312
  • 1
  • 8
  • 28
  • am not doing `remote: true`. Am serializing the input fields and sending it using jQuery ajax call. While sending tge request, am making the `authenticity_token` as nil(for testing). Still the request is processed without any error. But when I send the request from postman without authenticity_token I get the error. – Anand Hegde Jun 01 '18 at 14:29
0

This token is automatically added in as hidden field when you are using form_for helper method to generate forms, so Rails makes sure the request comes from one of your forms.

You should unprotect your controller action when requested from postman or any other app, see how to here : https://stackoverflow.com/a/22715175/8352929

adesurirey
  • 2,204
  • 1
  • 9
  • 31
0

You can find how CSRF works from here. I recommend you go through it.

Whenever you use form_for Rails adds one hidden input field to your form which looks like the following:

<input type="hidden" name="authenticity_token" value="doLYVxrkhdrzn7zzriHXjFE6ZhNCuXVxLrau4ouENmuKKC/SWp2NMM/MeL/Ji2tDvzNcJHVN/Hc0LIluL3o5QQ==" />

Also, Rails include CSRF token in the meta tags of the website which looks like the following:

<meta name="csrf-token" content="zxnmBxg81JUQPG/C/wb3HRCah0m9Xe2A+gZ5N0Oy7cfwC+dF4hC325WxdVDLfkIxcw/CR/xyaC1phpvZ4EcgQw==" />

So, when you use Rails form_for or something similar to make AJAX call(may be with remote: true) the authenticity token is sent to the server. Which was not present when you tried to send the same request with Postman.

If you copy the CSRF token and add it to Postman params, the request will be completed successfully.

Kartikey Tanna
  • 1,331
  • 8
  • 22
  • I have commented for one of the answer above, still I will paste that here again. I am not doing `remote: true`. Am serializing the input fields and sending it using jQuery ajax call. While sending tge request, am making the `authenticity_token` as nil(for testing). Still the request is processed without any error. But when I send the request from postman without authenticity_token I get the error. – Anand Hegde Jun 01 '18 at 14:35
  • Can you confirm the same by checking `params` under server logs? And also please update your question with the information – Kartikey Tanna Jun 01 '18 at 14:38
  • `jquery-ujs` automatically adds CSRF token while using POST with jquery. Ref: https://stackoverflow.com/questions/35162218/jquerys-ajax-function-automatically-adds-csrf-token – Kartikey Tanna Jun 01 '18 at 14:42
  • I am manually making the `authenticity_token` nil before making AJAX request. I checked in the server log, token is coming as blank. That's why I got confused. How come the request is authenticated without the `authenticity_token`? In that case it should have worked with postman also – Anand Hegde Jun 01 '18 at 15:36
  • Can you dump the server logs and jQuery code responsible for the AJAX call in the question? – Kartikey Tanna Jun 01 '18 at 17:45