Ruby on Rails POST parameters on redirect_to - ruby-on-rails

I have to make a call to a different url in one of my controllers on my site. The problem is that with all the parameters the other site requires I'm overflowing the url. Is there anyway to call another url from the controller and send all of the parameters using a POST?
I'm not expecting a response from the other site. Also, I think there's a way to do this using the Net::HTTP library thought I'm not sure how.
Thanks

You can't do a redirect and send POST data at the same time in the HTTP spec. Redirects are implemented by sending a simple Location: otherlocation.html header. POST data doesn't fit anywhere into that system.
Do you want the user to go to this page, or do you want to just send the data to the application yourself? If you want to send the data and not send the user there, use Ruby's Net::HTTP module. If you want to send the user, you may be forced to output a view with a form, and submit it automatically with Javascript. (Don't forget to degrade gracefully by offering a submit button in noscript tags.)

This is from the ruby docs:
require 'net/http'
require 'uri'
result = Net::HTTP.post_form(URI.parse('http://www.example.com/search.cgi'),
{'q'=>'ruby', 'max'=>'50'})
As you can see, you pass the params in as a convenient hash, unlike other languages that make you mess with http formatting.

You can also use the flash to transfer the information.
http://guides.rubyonrails.org/action_controller_overview.html#the-flash

Related

How to change GET to POST

I have one web application running on Struts. User is hitting below url directly from browser -
http://:/Test/servlet.do?name=XX&address=YYY
By default this request is submitted as GET by the user. Now my question is
1) how do I change user request to POST?
Use JQuery post or ajax methods, using an empty form with hidden keys.
There are plenty of browser add-ons that will let you send your request as POST (such as DHC by Restlet and Advanced REST client for Chrome)
Remember GET is inside the ans is set into links. POST are usually done by , or GET is possible too. So hitting a URL or link as you said is not possible to do over html, use PHP or Jquery so have it GET instead .

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 cross-domain requests security concerns

I am developing a Rails app which relies on a lot of jQuery AJAX requests to the server, in the form of JSONs. The app has no authentication (it is open to the public). The data in these requests is not sensitive in small chunks, but I want to avoid external agents from having access to the data, or automating requests (because of the server load and because of the data itself).
I would ideally like to include some kind of authentication whereby only requests can only be made from javascript in the same domain (i.e. clients on my website), but I don't how or if this can be done. I am also thinking about encrypting the query strings and/or the responses.
Thank you.
What do you mean only your app should request these JSONs? A client will eventually have to trigger an event, otherwise no request will be sent to the server.
Look at the source code of any of your app's pages. You will notice an authenticity token, generated by the protect_from_forgery method in your application controller - from the api:
Turn on request forgery protection. Bear in mind that only non-GET, HTML/JavaScript requests are checked.
By default, this is enabled and included in your application controller.
If you really need to check whether a request comes from your own IP, have a look at this great question.
I want to avoid external agents from having access to the data... because of the server load and because of the data itself.
If you're really concerned about security, this other question details how to implement an API key: What's the point of a javascript API key when it can be seen to anyone viewing the js code
You shouldn't solve problems you don't have yet, server load shouldn't be a concern until it actually is a problem. Why don't you monitor server traffic and implement this feature if you notice too much load from other agents?
I ended up passing token=$('meta[name=csrf-token]').attr("content")in the request URL and comparing with session[:_csrf_token] in the controller.
def check_api
redirect_to root_url, :alert => 'effoff' unless request.host =~ /yourdomain.com/
end
that should work to check your domain. Not sure you need the js part, but it's something.

Setting HTTP Headers for Rails form_for

I am currently working on an avatar app powered by Rails where users can upload avatars for their user profile.
I would like to use a custom HTTP header to block public upload requests and only allow requests from my apps. How would I go about doing this with Ruby on Rails?
I am uploading the avatars using AJAX so this may be a bit harder. Also I would prefer not to show the header in the public HTML code otherwise it defeats the object of adding it!
If you add
protect_from_forgery
to your application controller, it will block all NON Get requests from 3rd party links. It will add a hidden input value to each form with an authentication token that will be used to check all data that is sent to the servers.
Further reading
http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf
http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
Rails 3.1 - CSRF ignored?
You could implement a custom HTTP header (say X-Foobar-Validity-Status: valid) and check it in a before_filter.
class YourController < ApplicationController
before_filter :check_header
def check_header
unless request.headers['X-Foobar-Validity-Status'] == "valid"
render json: {"error" => "You are an evil attacker. Go away"}
end
end
end
However, I would consider this a bad idea.
Attackers can read the packet dump of your HTTP requests and add the headers, even with jQuery. See the jQuery.ajax headers option.
Instead of using a proprietary header, I would use User-Agent for this purpose.
Instead, I would sugest using the protect_from_forgery mechanism of rails. It makes your life easier and is more secure. Just fetch the authenticy token by a http request in your app and then send it back with your request. This should keep intruders out.

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.

Resources