An OmniAuth strategy for use with ActiveModel's has_secure_password
Ruby JavaScript
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
lib Switch to singular resource for session Mar 4, 2012
spec Switch to singular resource for session Mar 4, 2012
.gitignore Initial commit Mar 1, 2012
CHANGELOG Add changelog Mar 4, 2012
Gemfile.lock Add integration specs using dummy app, basic functionality passing Mar 3, 2012
MIT-LICENSE Add more instructions to README Mar 4, 2012


The OmniAuth Password gem is designed to be a simple way to add local login/password authentication along side other strategies. It simply makes ActiveModel's has_secure_password work directly with OmniAuth like any other provider without the need for a separate Authentication or Identity model.

This gem will work well for you if you want to create your authentication system from scratch. Authenticating to a local User model is treated just like authenticating to an external provider like Twitter. OmniAuth Password stays out of your way leaving local user registration up to you. It does not provide controllers or views.


Add the strategy to your Gemfile

gem 'omniauth-password'

Add the following to your config/initializers/omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do
  # provider :twitter ...
  # provider :github ...
  provider :password

Add some routes:

  match "/auth/:provider/callback" => "sessions#create"
  match "/auth/failure", to: "sessions#failure"
  resource :session

OmniAuth Password expects a POST to /auth/password/callback with login params in the session hash. You might create a form something like this:

<h1>Sign in</h1>

<%= form_for(:sessions, url: "/auth/password/callback") do |f| %>
  <div class="field">
    <%= label_tag :email %><br />
    <%= f.text_field :email %>
  <div class="field">
    <%= label_tag :password %><br />
    <%= f.password_field :password %>
  <div class="actions">
    <%= submit_tag "Sign in" %>
<% end %>

Your Sessions controller's create method takes the omniauth hash from this and any other strategy you are using; it might look something like this:

class SessionsController < ApplicationController
  def new

  def create
    user = User.from_omniauth(request.env["omniauth.auth"])
    session[:user_id] =
    redirect_to root_url, notice: "Signed in"

  def destroy
    session[:user_id] = nil
    redirect_to root_url, notice: "Signed out"

  def failure
    redirect_to new_session_path, notice: "Authentication failed"

The User model does not need a uid field for OmniAuth because it reuses the password_digest field when not doing local login/password authentication. ActiveModel's has_secure_password causes password_digest to be a required field.:

# == Schema Information
# Table name: users
#  id              :integer         not null, primary key
#  email           :string(255)
#  provider        :string(255)
#  password_digest :string(255)

class User < ActiveRecord::Base

  def self.from_omniauth(auth)
    find_by_provider_and_password_digest(auth["provider"], auth["uid"]) || create_with_omniauth(auth)

  def self.create_with_omniauth(auth)
    create! do |user|
      user.provider = auth["provider"]
      user.password_digest = auth["uid"] = auth["info"]["name"]


By default, OmniAuth Password expects to authenticate to the email and password of the User model. You can override these in your config/initializers/omniauth.rb:

Rails.application.config.middleware.use OmniAuth::Builder do
  # provider :twitter ...
  # provider :github ...
  provider :password, :login_field => :username, :user_model => Admin