In this fifteenth part of an eighteen-part series on the Action Pack library for Rails, you'll start learning how and why to use control filters. This article is excerpted from chapter six of the book Beginning Rails: From Novice to Professional, written by Jeffery Allan Hardy, Cloves Carneiro Jr. and Hampton Catlin (Apress; ISBN: 1590596862).
Action Pack and Controller Filters - Requiring Authentication with Filters (Page 2 of 2 )
In our events application, we’ve decided that we want to protect event creation and modification, restricting access only to registered users. To do this, we’ll use filters that call specific methods and check for the user_id session we set upon user login. Recall that any methods we add to the application_controller are available to all other controllers (since it’s the superclass of all controllers).
Open the application_controller in app/controllers/application.rb and add the private methods that we’ll use to enforce our authentication requirement, as shown in Listing 6-21.
class ApplicationController < ActionController::Base
# Returns the currently logged in user or nil if there isn't one
return unless session[:user_id ] @current_user ||= User.find_by_id(session[:user_id]) end
# Make current_user available in templates as a helper
# Filter method to enforce a login requirement
# Apply as a before_filter on any controller you want to protect
logged_in? ? true : access_denied end
# Predicate method to test for a logged in user def logged_in? current_user.is_a? User end
# Make logged_in? available in templates as a helper
flash[:notice] = "Please log in to continue"
redirect_to login_url and return false
The current_user method acts like an accessor for the currently logged-in user. Since it returns a User object, we can call instance methods of User on it, such as current_user.login . The authenticate method is our filter method (the one we’ll call from individual controllers). It checks whether there is a currently logged-in user via logged_in? (which, in turn, checks that there is actually a User returned by current_user ) and calls access_denied , if there isn’t. access_denied sets a message in the flash and redi rects to the login action on the users controller.
We want two of these methods available in templates as well: logged_in? and current_user . Having logged_in? available will allow us to make dynamic decisions about whether or not a user is logged in. We can use this to show or hide administrative controls (such as adding or editing a given event). Having current_user around will also prove useful in templates, allowing us to access information about the users such as their login name or email address. Rails provides a handy way to extend the visibility of methods to templates by declaring them as helpers. You can use helper_method followed by a symbolic reference to the method in question, as we’ve done here. You can also pass an array of method references to helper_method if you want to declare them all at once.
Let’s apply the filter to our events controller now. We’ll also apply a filter to the users controller to restrict who can edit user profiles.
Please check back regularly for the next part of the series.
DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.