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"

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

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


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

  helper_method :authenticate

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

class ExampleController < ApplicationController
  before_filter :authenticate

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