-
Notifications
You must be signed in to change notification settings - Fork 0
Notes on using the Clearance gem for Auth
Many applications contain user authentication code. Authentication is the management of the user session (sign-in and sign-out) and the existence of users in the system (sign-up). This is different from user authorization, which defines what users can and cannot do in a system once they log in.
Because the great majority of applications require user authentication, this has been an area of collaboration on open-source plugins for some time in the Rails community. Unfortunately, many of the user authentication plugins in the past have had a few problems. Having been around for some time, they often contain old, outdated code that is not up to current best practices and may be difficult to understand. In addition, plugins tend to try to be all things to all people. They frequently have configuration options for various ways of doing things, such as password encryption, optional user parameters, different login or user creation flows, and so on. Unfortunately, this results in an overly complex login system that can be confusing to a developer. You can sometimes overlook such downsides when your authentication system needs to look and behave exactly like what is provided by the plugin. However, if you need to customize or improve something, it can be very difficult to do so in the context of the framework provided by the plugin.
What are you to do when faced with the need to add user authentication to an application? You may think that your only options are to use a plugin and have potential pain down the road or to take the time upfront to write your own, thereby potentially reinventing the wheel and potentially ending up with a system just as poorly written as the plugin, if not more so.
First, you should not write your own plugin. Rolling your own authentication system requires time and effort for something that is now effectively a solved problem. There are simply too many pitfalls involved in writing your own. Consider the additional functionality that will inevitably be part of any production authentication system: password resets, “remember me,” email confirmations, and so on. What might start off as a simple task eventually turns into custom written code that is inevitably a liability.
Fortunately, there are now several newer gems that take new, cleaner approaches to user authentication, are written using current best practices, and have limited scope in order to provide a solid basic authentication system without providing so much that it becomes a burden.
In the following solutions to this AntiPattern, we present the two of these newer gems, Clearance and Authlogic. Which gem you should use depends on the exact needs of the application. However, the choice to write your own authentication code should no longer be considered an option except in the most extreme circumstances. The gems described in this chapter have been used successfully in many different types of applications.
One of the gems that has emerged as an antidote to overly complex authentication plugins is Clearance. It includes sign-up, sign-in, sign-out, and password reset functionality—and nothing more. It seeks to provide a clean, straightforward authentication system while providing a test suite that can be integrated into your own application’s test suite to ensure that its functionality, as well as any functionality you have customized, is well tested. You can obtain the Clearance source code from http://github.com/thoughtbot/clearance. While you can install Clearance into an existing application, it’s usually better to have user authentication added as one of the first things in your new application. It’s easier to understand what’s going on and manage the changes that way.
Clearance is a Rails engine. Rails engines, in contrast to generators, enable plugins to provide actual functionality to an application without copying the source code for models, controllers, and views directly within the application’s source code. Engines stay inside the gem. The benefit to this is that you can upgrade a gem and get the new functionality, such as bug and security fixes, in a relatively straightforward manner. View the README for Clearance for the full, up-to-date installation instructions, as well as more information on specific advanced Clearance topics. Here we highlight a few important topics that will hopefully give you an idea of the strategy that Clearance takes, contrast it with the other gem presented in this AntiPattern, and allow you to get started with it. To install the Clearance gem, bundle the clearance gem into your Rails application. Next, from within your Rails application, you run script/generate clearance to configure your application for Clearance. You need to insert Clearance into the appropriate places in your controllers and routes, and you need to generate the migrations for your database. After running the generator and following any additional instructions given, Clearance is ready to go in your application. You should now have /sign_in, /sign_up, /sign_out, shortcut URLs, and a functioning authentication system. If you want to require users to be logged in to access a specific controller or controller action, you accomplish this with the :authenticate before filter:
class class WidgetsController < ApplicationController before_filter :authenticate
def index
@widgets = Widget.all end
end
To change any of the actions provided by Clearance, you simply subclass the controller provided by Clearance. For example, to change the behavior of the new action of the sign-in controller, you redefine it in your subclass as shown here:
class SessionsController < Clearance::SessionsController def new
# your special new behavior end
end
Then you add the route for your new controller before the Clearance routes in config/routes.rb, as shown here:
map.resource :session, :controller => 'sessions'
You can override actions that redirect (create, update, and destroy) in Clearance controllers by redefining url_after_(action) methods as shown here:
class SessionsController < Clearance::SessionsController def url_after_create
your_special_path end
end
One of the features that sets Clearance apart from other gems is that it provides complete Cucumber integration tests for your application to use as base tests for the authentication logic Clearance provides. A generator put these in place, and they run along with the rest of your integration tests. To generate the Cucumber features, you simply run the following command:
script/rails generate clearance_features
If you modify existing functionality, you can modify the Cucumber features accordingly. This should make adding or customizing functionality easier, without introducing regressions to the authentication logic.