Ruby on Rails went open source in late 2004, and open to commit changes in 2005. Since then, some solutions appeared to solve common problems like authentication, a common requirement in Web applications. Here’s my brief analysis of how authentication solutions have evolved, what we have to work with right now, and how to select the right one based on how it will be used.
A Long Time Ago, in a Galaxy Far, Far Away….
acts_as_authenticated and rest_full authentication and login engine were the preferred tools to solve authentication issues. As the Web became more interconnected and complex — and the Ruby on Rails community grew — new plugins/gems improved the quality of authentication solutions.
Github’s git platform for social coding connected developers and facilitated the contribution to existing projects. (Previously, Ruby code was distributed in several svn repos, so collaborating and proposing changes was difficult and tedious.)
The new babies, Authlogic and clearance, played the opposite roles: Authlogic offers a ton of features while clearance tries to be as simple as possible. Authlogic — originally called Authgasm — began with Rails 2.1
Let’s take a look at the common use cases for authentication in a Web application.
- Web applications that include just one role, such as “User.”
- Applications that need more than one role, like “Admin” and “User.”
- Applications that use third-party authentication. For example, Twitter, Facebook, Google, etc.
- Web applications that use embedded Rails and Sinatra applications.
- Several Web applications that share users and credentials.
- Several Web applications that share users and credentials, and have several roles
- On application with one engine that uses its their own authentication system. And, remember, we don´t want to get the routes and controllers overlapped.
- Devise: A flexible authentication solution for Rails with Warden.
- Authlogic: A clean, simple and unobtrusive Ruby authentication solution.
- OmniAuth: A generalized Rack framework for multiple-provider authentication.
- Clearance: Rails authentication and authorization with email and password.
- Sorcery: Provides common authentication tools, such as signing in/out, activating by email and resetting passwords.
- Letmein: Provides minimalistic authentication.
- Warden: A Rack-based middleware designed to provide a mechanism for authentication in Ruby Web applications. It’s a common mechanism that fits into the Rack Machinery to offer powerful authentication options.
When I have to select an authentication solution for my Rails apps, I choose based on the features that I consider important in that case. Based on what you’re doing, be sure to consider these situations:
- Rack-Based: The authentication happens at the rack layer. Rack is the Ruby Web server interface.
- Custom Namespace Support: Support to easily define the namespace of the authenticated user in order to avoid conflict with other existing route/controller/model/view that may be used by other sub-apps.
- Oauth 1: Obviously, when you need support for OAuth 1.
- Oauth 2: When you need for OAuth 2. (You can check more about the widely used auth protocol here).
- Scopes: Allows you to create different namespaces for users, admin managers, etc. They can be authenticated at the same time.
- Rails 2.3: Works with Rails 2.3 or has a maintained version to support it.
- Rails 3.0: Works with Rails 3.0 or has a maintained version to support it.
- Rails 3.1: Works with Rails 3.1 or has a maintained version to support it.
- Sinatra: Allows you to share authentication with a Sinatra app inside a Rails app.
- Mongodb: Allows you to use mongodb as a persistence database, or any other db that you want to use.
- Email Activation: Supports the email activation process.
- Session Timeout: Supports the inactivity timeout to log out users automatically after some time.
- Engines: A nice Rails feature that allows you to have application modules that contais the full MVC stack, which you can plug inside your app.
- LOC / Complexity: Lines of code and complexity, their intrusiveness and, of course, test coverage.
- Easy to Include Authorization: Specify if integrations with gems like Can-Can are easy or supported.
- Encryption Algorithms: Today we can’t rely on some encryption methods like SHA1. Bcrypt is a good choice for encryption as a default.
You may want to start from scratch with Rails 3.1. In that case, this Railcast is a very helpful guide: #270 Authentication in Rails 3.1
As you can see, there’s no preferred one. Implementations can go from simple and minimalistic to fully featured, so some fit better for one specific use case, and others are better for different use cases. If you don’t have too many requirements for authentication, start from scratch, or choose the simplest one.