Omniauth is a simple rails gem that provides multi-authentication for web applications. For example, if you wanted to use have a facebook and twitter login for your app, Ominauth makes this easy to do. Omniauth Identity also makes it easy to add your own authentication, if a user didn’t want to use the other services. For this post, I’ll walk through adding Omniauth Identity to your rails app. This walkthrough assumes that you are currently not using any other Omniauth strategies (facebook, twiiter) yet, but provides the basics in case you add other strategies later.
This tutorial is based on Ryan Bates Railscast #304 http://railscasts.com/episodes/304-omniauth-identity
From terminal window run the following
>> rails g controller sessions
>> rails g model user provider:string uid:string name:string
>> rails g model identity name:string email:string password_digest:string
>> rake db:migrate
>> rails g controller identities
add the following to your Gemfile
gem ‘omniauth-identity’
gem ”bcrypt-ruby’, ‘~> 3.0.0’
Create omniauth.rb in config/initializers and add the below to the file
Rails.application.config.middleware.use OmniAuth::Builder do
provider :identity, on_failed_registration: lambda { |env|
IdentitiesController.action(:new).call(env)
}
end
Add the following to your Identity model, identity.rb
class Identity < OmniAuth::Identity::Models::ActiveRecord
validates_presence_of :name
validates_uniqueness_of :email
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
end
Add to your User model, user.rb
class User < ActiveRecord::Base
def self.from_omniauth(auth)
find_by_provider_and_uid(auth[“provider”], auth[“uid”]) || create_with_omniauth(auth)
end
def self.create_with_omniauth(auth)
create! do |user|
user.provider = auth[“provider”]
user.uid = auth[“uid”]
user.name = auth[“info”][“name”]
end
end
end
Add the below to your Sessions Controller, sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.from_omniauth(env[“omniauth.auth”])
session[:user_id] = user.id
render :text => ‘Signed in!’
end
def destroy
session[:user_id] = nil
redirect_to root_url, :notice => “Signed out!”
end
def failure
render :text => params[:message]
end
end
Add to your Identities Controller, identities_controller.rb
class IdentitiesController < ApplicationController
def new
@identity = env[‘omniauth.identity’]
end
end
Add to routes.rb
resources :identities
root :to => ‘sessions#new’
match ‘/auth/:provider/callback’ => ‘sessions#create’
match ‘/signout’ => ‘sessions#destroy’, :as => :signout
match ‘auth/failure’ => ‘sessions#failure’
Under views/sessions, create new.html.erb and add the following
<%= form_tag “/auth/identity/callback” do %>
<div class=”field”>
<%= label_tag :auth_key, “Email” %><br>
<%= text_field_tag :auth_key %>
</div>
<div class=”field”>
<%= label_tag :password %><br>
<%= password_field_tag :password %>
</div>
<div class=”actions”><%= submit_tag “Login” %></div>
<% end %>
<%= link_to ‘New User Sign up’, new_identity_path %>
Under views/identities, create new.html.erb and add the following
<h3>New Account</h3>
<%= form_tag “/auth/identity/register” do %>
<% if @identity && @identity.errors.any? %>
<div class=”error_messages”>
<h2><%= pluralize(@identity.errors.count, “error”) %> prohibited this account from being saved:</h2>
<ul>
<% @identity.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class=”field”>
<%= label_tag :name %><br>
<%= text_field_tag :name, @identity.try(:name) %>
</div>
<div class=”field”>
<%= label_tag :email %><br>
<%= text_field_tag :email, @identity.try(:email) %>
</div>
<div class=”field”>
<%= label_tag :password %><br>
<%= password_field_tag :password %>
</div>
<div class=”field”>
<%= label_tag :password_confirmation %><br>
<%= password_field_tag :password_confirmation %>
</div>
<div class=”actions”><%= submit_tag “Register” %></div>
<% end %>
Thanks for this. Helpful!