views:

330

answers:

2

I've been told that I shouldn't use variables such as params[:user_id] in my view files. Does the same rule apply to the session variable?

If not, then what should I be doing? Assign it to an instance variable first and then use that in the view? This seems annoying as I would have to do it for each of my actions. I guess I could put this repetitive code in one method which gets called by all the other actions in that class.

+1  A: 

You definitely want to verify params[:user_id] or session[:user_id] on every page load. If your session is hijacked, you could potentially put unwanted code into your view and allow a cross-site scripting attack.

That said, the proper method, used in the authenticated_system plugin, is to reference a current_user helper method that allows you to retrieve current_user.user_id.

Additionally, if you're using user_id in a call to the database, you should still verify it by calling @selected_user = User.find(params[:user_id] and using @selected_user.id in your view and controller action.

You'll get much more control and protection.

-Chris

Christopher Hazlett
+2  A: 

This recommendation comes from the best practice of "separation of concerns" between the different components that make up your Rails app. The best place to determine the current user is in your controller. This is where you would access your params and/or session to determine if someone is logged in, either directly or indirectly through an authentication plugin. Then, if you need this information in your view just store it in a variable such as @user which will be automatically available in your view for display purposes. Doing it this way, if you later change your authentication mechanism you can do so without touching your views, which is a good indication to you that you have a good separation between the different components in your app.

Also in response to the second part of your question:

I guess I could put this repetitive code in one method which gets called by all the other actions in that class.

This can be easily done with a :before_filter in your controller, which you can point toward a method that checks authentication and creates any necessary instance variables to be shared among the actions in your controller.

Adam Alexander