Sometimes we want part of the website to be available to specific users only. Either we don’t want our users to interact with a piece of functionality we are still working on or we want to show the new function to our client first, before making it available to the public. In both cases, we can’t let a single unwanted user to slip through our fingers.
The first idea that crosses developer’s mind in such a situation is creating an authentication system based on the session. Major drawback is the amount of work that must be put in the implementation. It is also possible that our last minute add-on will break the existing authentication system.
But there is another solution: HTTP basic authentication. It can be composed with existing web application in a harmless way. The mechanism is simple: when browser requests for restricted content, server responses with “401 Unauthorized” header. Browser should then send request containing password encoded using Base64 algorithm.
Fortunately, Rails makes our life a whole lot easier. We don’t have to worry about the technical details, because Rails provides a HTTP authentication method, ready to use out of the box. We can use the authenticate_or_request_with_http_basic() method, which can be easily integrated with existing application. The most common way to use it is to call it from a filter:
class ApplicationController < ActionController::Base USER, PASSWORD = 'boss', 'freak' before_filter :authentication_check ... private def authentication_check authenticate_or_request_with_http_basic do |user, password| user == USER && password == PASSWORD end end end
We have just added the before filter called
authentication_check(). The only thing it does is provides HTTP basic authentication. First, user is prompted for login and password. Provided that he entered correct values, he can see the page he requested and he can navigate through the website during the current browser session. If he fails to provide correct authentication data, he will see an error message. Simple, isn’t it?
In the code example we showed, whole application is being protected. But what if we want to use HTTP basic authentication in Rails to restrict access to particular action only? Well, it’s just a matter of filter configuration:
class BlogController < ApplicationController USER, PASSWORD = 'admin', 'reallystrongpassword' before_filter :authentication_check, :only => [:approve_comment, :delete_post] def index ... end def details ... end def comments ... end def approve_comment ... end def delete_post ... end private def authentication_check authenticate_or_request_with_http_basic do |user, password| user == USER && password == PASSWORD end end end