Rails not keeping session data when doing ajax with remote=true - ruby-on-rails

I am working with a rails app and trying to do an ajax request with rails remote: true . The request is supposed to trigger one of my controller actions.
<%= form_tag my_action_path(#version), {remote: true} do %>
In the application controller there is a before_filter callback which executes before the action is performed. It checks for session user id like so:
if session[:user_id]
This check fails forcing redirect. When I check session[:user_id] it's nil, which I guess means that the session cookie is not passed. I have a bunch of js that do ajax to the controllers and interestingly they all work, passing the check. So two questions:
Do I need some extra code to make remote:true work? Is there a way of setting a session cookie or smth?
Is this a correct way of verifying unauthorised ajax requests or is there a better way.
I'm using Rails 4
Thanks

I'm using devise, so I'm not sure if this is directly applicable, however, you also have to pass the authenticity_token in the form tag as well.
<%= form_tag my_action_path(#version), {remote: true}, authenticity_token: true do %>
It might be something separate, but similar. I think this will just work for you though.
Another thing to look at is look at a form that works and look at what data is posted to your server in the console, because rails echoes the data passed to the server and you can use this to help us help you debug. It should have session_id or authenticity_token or something similar in all session requests that work (anything you do while you're logged in).

Related

What is flash hash in ruby on rails

I am an experienced PHP developer but new to RoR and trying to understand how every thing works. I know how to use flash hash i.e in my action method, I'll set
flash[:notice] = 'some message'
and in my view, i'll display that.
This mechanism is also implemented in Yii framework. I understand how it works there. The thing that I don't understand is how it actually works here in RoR. flash is just a local variable then how can I access it in my views?
flash is actually a method. It's not in your controller, but the Rails controller delegates it to the request object. So the flash method is defined in the request object, but you can access it from your controllers, and from the view.
Check the link to the ActionDispatch::Request code. The flash is actually stored inside the session when set. The next time the user requests a page, the flash is accessible for use in the views.
In your view you can just access it like this:
<%= flash[:notice] %>
Or in a aesthetically more pleasant way (this can only be done with notice and alert since they're so frequently used):
<%= flash.notice %>
See the documentation for more information.
'flash' is not a local variable. It is part of session like 'session' hash. What this implies is that session hashes (flash, session, cookies) are shared values between ActionController::Base and ActionView::Base. Therefore session hashes are accessible from controllers and from views.In order to access flash in views, just use it as you would use it in controller. Referring to your earlier code , you would print notice like this:
<% if flash[:notice] %>
<p><%= flash[:notice] %></p>
<% end %>
For further reference on this topic please checkout: guides
The flash hash is basically a variable which is populated with each controller/action request, and then is reset after the request has been performed. As Adilbiy Kanzitdinov has mentioned - it's set in the session hash :
The flash provides a way to pass temporary objects between actions.
Anything you place in the flash will be exposed to the very next
action and then cleared out. This is a great way of doing notices and
alerts, such as a create action that sets flash[:notice] = "Post
successfully created" before redirecting to a display action that can
then expose the flash to its template. Actually, that exposure is
automatically done.
You need to remember that ROR is full-stack, meaning it has a bunch of middleware it uses to create the most efficient responses for your users. This allows you to set local variables (session, params, flash are 3 I can think of)
To call from a view, you just need to reference this local variable, as below:
<%= flash[:key] %>

Rails 3 - is link_to with parameters secure?

As a general rule of thumb you aren't supposed to trust any input of data from users. If you had a simple link_to with a parameter:
link_to "Click me", test_path(:my_param => "test")
The route might look like: example.com/test?my_param=test
How do I know if the param, or any injected data for that matter, is being filtered properly? The Rails 3 API doesn't specify that it filters data that is passed to the controller, but I want to make sure that the params[:my_param] is filtered securely in the controller before I utilize the params data.
Any thoughts?
Rails framework doesn't secure things by default for GET request. link_to tag is sending a http get request.
If it is a POST/PUT/DELETE request then the Rails uses protect_from_forgery for verify the data sending url
However in your case, its not hard to write a simple method to verify your data for get requests ,
you could write a before_filter to check the sending parameters for a GET request
HTH

can i use ruby on rails get and post for the same method?

I'm new to web development in general and ruby on rails in specific. I'm working on developing a web interface where i'm using a 'Get' and 'Post' requests on the same method. When i use a get method and send parameters (like username and password), they are being visible in the url. Hence, below is what i did.
form1.html.erb
<%= form_for :modify, :method => "post", :url => {:action => "method2"} do |f|%>
#code here to input username and password
<%=end%>
in my routes.rb i wrote the following routes to the method2:
post 'controller/method2'
get 'controller/method2'
When i enter username and password and click on submit, it is finding the post 'method2' and executing the code in the controller, and displaying method2.html.erb as there is a get request for the same method and also there is a view for method2.
However, i suspect this is not the right way to do it. I do not want the password to be visible. I came to know that i have two options, store the password in a session or send a post request. I do not want to store in session as it is not safe. When i write a post method the page expires when the user tries to come back. To prevent either of these happening, i used the same action in controller as post and get and now i do not see any parameters visible in the url.
Please let me know if this is not the right way to do
If you want a solid method for manipulating user & password, I recommend you go through the Ruby on Rails tutorial, it's an excellent tutorial and it will learn you the basics to start with Rails programming, including a safe username/password use.
Alternatively, you can use Devise, which is a very popular gem for this purpose.
I would not try to implement a secure user/password system without really knowing what you are doing...
In your controller you should have this :
render 'controller/method2'
And you should have a file in this path :
app/views/controller/method2.html.erb
You don't need to have two routes.

Form submission and hyperlinks using GET and POST

I have a search resource, the user can perform searches by filling out a form and submitting it, the create action is called, the Search is saved, the show action is called, and the results are displayed. This all happens with the default POST, and all works fine.
The user may want to save his search in the saved_search table (i don't use the Search table for this purpose as this table stores all searches for the purpose of compiling statistics, and gets cleared on a regular basis). Once the Search is saved, it can be re-run by clicking a hyperlink, this is where i start to get problems.
I see no way of getting my hyperlink to run the create action of Search, with a POST request, and the necessary data.
I then decided to try to get both form submission and the hyperlink to perform a search using a GET request, i was unable to get form_for to run my Search create action using a GET request, it always seems to get routed to my index action.
Can someone suggest a good restful solution to this problem please.
Many thanks
I'm not quite sure what you're trying to do here. If you want to have a form submit with a GET request, you can override the HTML attribute on the form_for helper:
<% form_for blarg, :html => { :method => 'get' } %>
blabla
<% end %>
Rails also supports a way of "faking" the HTTP method by using a "magic" parameter (called "_method"), which makes Rails behave as if it had seen the HTTP method in that parameter.
If you send the form as "get", you must make sure that none such parameter is set. If you wanted to let a hyperlink send a "POST", tweaking this would be the way (a browser will not send a real POST on a click on a link)
Jon,
If I understood right, if the search is already saved, you could just make a get on the resource of the saved search like you did the first time and use the show action to display the result.
Anyway, if you still wants to do a post with a link, the helper method link_to does it for you. Check it out:
http://www.51773.com/tools/api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#M001597
With a :method => :post option it will create a hidden form and post your data.
Hope it helps.

Is there any harm in using a typical GET action for a PUT? (RESTfully speaking)

I have an action that doesn't require a form. So it really only needs the one 'edit' method instead of the RESTful 'edit' --> 'update'. Is there any reason not to do this or a better way?
def edit
#Do a POST(PUT)
end
The harm is that a user could easily navigate to that url and perform a potentially destructive action.
/noform/edit #URL typed by user => Action Performed
/noform/update #URL typed by user => Error is thrown, No Action Performed
A normal browsing experience generates GET requests to the server. The assumption is, any page you can easily navigate to (or type into your address bar) will not perform any data changing functions.
A POST request, generated via a form submission or a AJAX request expects the result that data is changed on the server.
Similarly the two rails "faked" versions of PUT and DELETE also are not actions you could simply navigate to using a browser.
The solution
The solution is to have only the update action and where you originally would have linked to edit use something like the following:
button_to "Add new tracker", noform_path, :method => :put
If there is any type of error, you may still need an edit path to show the user so they can correct something. But from what you have described, a single update action should do the trick.
Gets should always be idempotent -- that is they should not perform any action that will alter the state of the application, database, etc.
Just as an aside -- in true RESTful form an edit would be performed by an HTTP Update action, but Rails simulates this with a post and a hidden value on the form, since browsers don't have HTTP Updates.
It's still not clear to me why you need an update without an input field. Perhaps a little more detail would be helpful.

Resources