Do Ruby on Rails 3 Jquery AJAX POST requests need the authenticity_token? - ruby-on-rails

According to the Rails security guide, if you use protect_from_forgery, all non-GET requests include an authenticity token. When I have Jquery AJAX POST requests, however, I don't see the authenticity_token param as one of the params in the request. Is this how it's supposed to work?
Also, it seems that POST requests from outside a session (curl in a script) don't require an authencity_token, either.
Thanks!

Rails will send this parameter in the headers rather than in the post data. You need to include the built in rails UJS library to get this to work. Take a look at the headers in your request and you should see one called X-CSRF-Token.

Related

Rails CRUD operations using AJAX

I'm developing a Rails app. I have generated all my resources using the scaffold generator, and now I'm working on javascript, on an AJAX function.
I saw that if I request /entities/1.json, it returns JSON data for the record with id=1, so I was wondering if it's possible to do other CRUD operations the same way with GET/POST http requests using routes like /entities/new.json or so, that is, make an AJAX request sending post data as JSON.
Can you guide me on how to do that?
As you saw, scaffolds generates proper url and code for both HTML and json, so sending a POST to create a resource should work without problems.
You can find more info in the Rails guides about JavaScript and JSON

How to pass CSRF token for Rails post request in paw-app

I am attempting to use the Paw app to test out a REST API build in Rails 4.2.4. I have a create method which expects JSON as input. The request appears to pass the correct information from Paws as structure, but the Rails API is failing with the following error:
422 Unprocessable Entity
Can't verify CSRF token authenticity
When writing the JavaScript front end, the request must have a header appended to the request, of the form:
webix.ajax().headers({'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}).post("geo_wells.json", parms), function(text){webix.message("posted");});
That all works fine for getting the CSRF satisfied consistently, although it's the parms I am trying to use Paws to help sort out. But I can't get that meta token in Paws. No idea how to actually add that to the header of the request. Tried creating a cookie and all response cookies, but that didn't do it either.
Any ideas? I'd like to purchase the tool, but if it can't do this, it's not of that much use to me. I would prefer not to up and disable the CSRF as is so often suggested. I'm hoping for a robust answer that would still extend to testing of the fully CSRF enabled API.
This Paw.app article had the answer.
First, install the RegExMatch extension.
See: https://paw.cloud/extensions/RegExMatch
With the Ruby on Rails getting started set up, the regex required to get the csrf token was below:

In rails app who respond according to the http request?

Well, so far in each article I see people say server respond accordingly to the request type. If it is xml request then response is in xml and if it is ajax or html then response is in ajax or html. Browser send the request and server respond accordingly. My question is in rails app in which part this decision is taken? That is by server which part of the rails app we indicate?
This decision is taken inside the controller of the rails MVC framework and can be modified by the user. The user may wish not to respond to a particular type of request.
The distinction is made by suffix in URI, eg. ..../users/123.json. And You do it by yourself in controller.

Rails POST doesnt extract any path, query or request parameters

I want to grant users access to my API (hosted on heroku.com) from their sites.
But a strange problem occurs, when i want them to allow to post to the api:
Data sent from an correct form with the correct action-url (e.g. "http://myapp.com/projects/123/tasks/321/todos") - the params get serialized and send via jQuery - i encounter an "ActionController::MethodNotAllowed" with the additional info: "Only get and post requests are allowed", that re-routes to ApplicationController#index with :method => :options.
Rails doesnt extract the params for project_id (123) and task_id (321) from the url, neither are any further request_parameters, path_parameters or query_parameters available.
This behaviour occurs, when I POST from external sites, but doesn't occur, when posting from an html-page on my local machine. My first thought was about wrong encoding, but how to fix that problem.
Edit:
I am using authlogic (not devise :-D) and for the :create action the protect_from_forgery is already skipped.
Any suggestions appreciated
i guess that happens because rails tries to protect your form CSRF attacks.
you can comment out the protect_from_forgery line in your ApplicationController to test it.
but im not sure if thats the right way of dealing with this issue in the production environment.
Okay. I'll try and answer the right question this time (see other comment).
So I've thought about this, and I'm wondering, is this a case of the jQuery call attempting a PUT request? When you use the local form Rails will POST the data, but add the extra _method field to emulate a PUT.
Don't know if you are using jquery-rails, but this takes care of setting the _method parameter, and the PUT/POST verb translation for you in your AJAX calls.
The problem occured due to the cross domain policy - the request was made from another domain - and because I was using a recent browser that supports CORS, it was sending an OPTIONS-request first to get known from the server, which actions are allowed for this domain.

Rails, REST Architecture and HTML 5: Cross domain requests with pre-flight requests

While working on a project to make our site HTML 5 friendly, we were eager to embrace the new method for Cross Domain requests (no more posting through hidden iframes!!!). Using the Access Control specification we begin setting up some tests to verify the behaviour of various browsers.
The current Rails RESTful architecture relies on the four HTTP verbs: GET, POST, PUT, DELETE. However in the Access Control spec, it dictates that non-simple methods (PUT, DELETE) require a pre-flight request using the HTTP verb OPTIONS. In addition during testing we discovered that Firefox 3.5.8 pre-flight POST requests as well.
My question is this. Is anyone aware of any project for the Rails framework working to address the issue? If not, any opinions about the best strategy to support the OPTIONS method, since it has to support the routes for all the POST, PUT, DELETE methods?
I released a Gem a couple of days ago that implements CORS support via a Rack Middleware:
http://github.com/cyu/rack-cors
Regarding preflight CORS requests, I couldn't get preflight requests working in Chrome (through simple CORS requests work fine). Searching around the Internets suggests that it might not be supported. I've asked questions in the Chrome forum about this, but haven't heard a response yet.
This is from Spine js documentation
CORs Rails integration
Let's create a cor method, which will add some of the request access control headers to the request's response.
Add the following to app/application_controller.rb:
before_filter :cor
def cor
headers["Access-Control-Allow-Origin"] = "js-app-origin.com"
headers["Access-Control-Allow-Methods"] = %w{GET POST PUT DELETE}.join(",")
headers["Access-Control-Allow-Headers"] = %w{Origin Accept Content-Type X-Requested-With X-CSRF-Token}.join(",")
head(:ok) if request.request_method == "OPTIONS"
end
Although Access-Control-Allow-Origin takes a wildcard, I highly recommend not using it as it opens up your app to all sorts of CSRF attacks. Using a whitelist is much better and more secure.
The Access-Control-Allow-Headers section is important, especially the X-Requested-With header. Rails doesn't like it if you send Ajax requests to it without this header, and ignores the request's Accept header, returning HTML when it should in fact return JSON.
It's worth noting that jQuery doesn't add this header to cross domain requests by default. This is an issue that Spine solves internally, but if you're using plain jQuery for CORs, you'll need to specify the header manually.
jQuery.ajaxSetup({
headers: {"X-Requested-With": "XMLHttpRequest"}
});
Some browsers send an options request to the server first, to make sure the correct access headers are set. You'll need to catch this in Rails, returning a 200 status with the correct headers. To do this, add the following to your application's config/routes.rb file:
match '*all' => 'application#cor', :constraints => {:method => 'OPTIONS'}
That's it, you're all set up for Cross Origin Requests with Spine!
I hacked rails to support the options method. I posted this on the rails list, but it never made it past the list.
GitHub Gist: Rails XHR2 / CORS / OPTIONS support
ctrl+f to find the lines that have #Options - those are the only ones I changed.
And here's an example implementation | and another

Resources