Andreas Pfohl

HTTP Basic Auth from Database

As you already know you can easily add some authentication to your rails app by adding something like this to any of your controllers.

class ExampleController < ApplicationController
  http_basic_authenticate_with name: "username", password: "secret"
end

The disadvantage is apparent. You can set only one user. The solution is to add some functionality to your rails app to authenticate against a database model.

At first you need a model to hold your authentication data. Let’s call it User.

$ rails g model user username:string password_digest:string

Of cause you want to use encrypted passwords in our database. To get this, you should add has_secure_password to your user model.

class User < ActiveRecord::Base
  attr_accessible :username, :password, :password_confirmation
  has_secure_password
end

This adds some functionality that helps you handling the authentication against your model.

It is advisable to add an authentication helper method to your ApplicationController.

class ApplicationController < ActionController::Base
  protect_from_forgery

  private

  def authenticate
    authenticate_or_request_with_http_basic("Application") do |name, password|
      user = User.find_by_username(name)
      user && user.authenticate(password)
    end
  end

  helper_method :authenticate
end

You can now use this helper method as a before_filter in your controllers.

class ExampleController < ApplicationController
  before_filter :authenticate
end

That’s it. You now can add some users with passwords using the rails console and the authentication will work.

$ rails c
irb(main):001:0> User.create(username: "alice", password: "ilovebob")
(0.1ms)  begin transaction
Binary data inserted for `string` type on column `password_digest`
SQL (5.4ms)  INSERT INTO "users" ("created_at", "password_digest", "updated_at", "username") VALUES (?, ?, ?, ?)  [["created_at", Wed, 16 Jan 2013 09:07:34 UTC +00:00], ["password_digest", "$2a$10$lJWyivuQjjwFlQVadpEDSuFXbMfgC7LQn58tp5aPSrdS1S6jFB9/6"], ["updated_at", Wed, 16 Jan 2013 09:07:34 UTC +00:00], ["username", "alice"]]
(2.5ms)  commit transaction
=> true

#250 Authentication from Scratch
http_basic_authenticate_with