Restricting Access

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

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