We can check if a user is logged in by testing the session variable (i.e. session[:user_id]). Here we restrict access to specific actions by checking the login status.
Filters are methods that are called before or after a controller action is executed. Here we focus on Before Filters, which are called before a controller action is performed. The before filter provides an opportunity to check for valid login and redirect the request if the current action is not authorized.
Here are examples of declaring a filter in a controller (placed before any of the action methods):
# run this filter before all requests before_filter :authorization # run this filter before all requests except for the index action before_filter :restrict, :except => :index # run this filter only for the new and create actions before_filter :prepare, :only => [:new, :create]
Filters can then be declared later in the controller (they should follow a proctected or private declaration). Alternatively, they can be defined in the application controller if they will be used by more than one controller.
Here is an example that prevents access to all actions unless a user (any user) is logged in:
def authorization unless session[:user_id] # not logged in # first save url of the current request session[:last_request] = request.fullpath # go to login page redirect_to login_path end end
Alternatively, you may want to restrict access to specific users:
def restrict user_id = session[:user_id] if user_id @user = User.find(user_id) unless @user.admin # if user is not admin, show the view auth_error.html.erb render :action => 'sessions/auth_error' end else # not logged in # first save url of the current request session[:last_request] = request.fullpath # go to login page redirect_to login_path end end
Note how both of these methods save the URL of the current request. That way, the login action can return the user to the requested page after the user is logged in. To benefit from saving the URL, the login action (aka create) in the sessions controller should end with the following code:
if session[:last_request] next_path = session[:last_request] session[:last_request] = nil else next_path = root_path end redirect_to next_path