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

That’s all!

comments powered by Disqus