Authentication is what you do when you let a user identify itself. This is needed when you want to offer a login access to your application.
Authorization is what you do when you check the credentials of a user before letting him/her interact with specific sections of your system. This is needed when you have restricted areas/actions.
Although Ruby on Rails does not have a built-in authentication framework, many applications built on Rails needs to support authentications for purposes of user identification, access control and interaction between various users. Developers can choose to utilize an existing authentication framework in either plugin or gem form, or build their own authentication system from scratch.
Both custom-built, and pre-packaged authentications will generally need to support the following activities, at a minimum:
In addition, there are a number of other features that one may wish to consider before choosing an authentication system:
The following is a list of how-tos for installing some of the most popular authentication frameworks available for us with Ruby on Rails. These are the most common candidates, not an exhaustive list of all available packages.
Using an existing authentication package for your project has advantages beyond the immediate savings in development effort. Integrating an actively supported packages will allow you to avoid maintenance tasks such as adding updated encryption algorithms or supporting new methods of authentication (e.g. OpenID). Additionally, using an existing framework leverages the efforts of other developers to find and patch any security holes in the framework. Unless your project has unusual needs in terms of its authentication system, an existing framework is often the most practical choice.
If your projects has custom needs related to authentication you may want to build your own authentication system.
At its most basic this can be done by creating:
Session status can be stored using the session container, which stores any new values added to it in the cookies on a user's browser.
For example:
session[:user] = 'foo'
It is generally preferable to store only the primary key of a record in the session container rather than attempting to store an entire ActiveRecord object or all of its fields in the session container.
session[:user_id] = current_user.id
…rather than…
session[:user_name] = current_user.name
This helps minimize situations where the data stored in a user's browser cookies has become stale between requests due to data in the Rails database getting updated or otherwise modified.
To implement access control, before filters can be used on controller methods that should require a user to be logged in.
class FoosController < ApplicationController before_filter :require_user protected def require_user # method code end end
(The require_user method would likely be located in application.rb or another shared file, rather than existing in the controller for a specific model.)
Implementation of session creation and destruction should most likely be implemented using a RESTful pattern as supported by rails. Having separate user and session controllers makes it significantly more easy to implement a REST authentication scheme.
For a tutorial on how to implement gradual user engagement using Rails and the restful authentication plugin, see Kill your signup form with Rails. Gradual user engagement allows you to avoid losing users who don't want to fill out a signup form (which is most of us)
Discussion