Hi I am using omniauth in my application. I created the application without using devise. So I wrote all the methods for encryption manually. I am trying to integrate imniauth with my application but I am encountering loads of problems. I made an authentications controller:
class AuthenticationsController < ApplicationController
def index
@authentications = current_user.authentications if current_user
end
def create
omniauth = request.env["omniauth.auth"]
authentication= Authentication.find_by_provider_and_uid(omniauth['provider'],omniauth['uid'])
if authentication
flash[:notice]= "Signed in with " + omniauth['provider'] + " Successfully"
sign_in(authentication.user)
redirect_back_or authentication.user
elsif current_user
current_user.authentications.create!(:provider => omniauth['provider'],:uid => omniauth['uid'])
flash[:notice]="authentication successfull"
redirect_to authentications_url
else
authenticate= Authentication.create!(:provider => omniauth['provider'], :uid => omniauth['uid'])
flash[:notice] = "You still need to fill up the following"
# This is where I have doubt as to how should I proceed. Should I first create authentication for omniauth and then redirect or just send everything together and then create in sign up?
# session[:omniauth] = omniauth.except('extra')
# redirect_to signup_path(omniauth)
end
end
def destroy
@authentication = current_user.authentications.find(params[:id])
@authentication.destroy
flash[:notice] = "Successfully destroyed authentication."
redirect_to authentications_url
end
end
My User controller is as follows:
class UsersController < ApplicationController
before_filter :authenticate, :except => [:show, :new, :create]
before_filter :correct_user, :only => [:edit, :update]
before_filter :admin_user, :only => :destroy
# Id ont know what to do with omniauth here! :(
def new(omniauth)
@user = User.new
@title = "Sign up"
end
def create
@user = User.new(params[:user])
if @user.save
sign_in @user
redirect_to @user, :flash => { :success => "Welcome to the World Student Alliance!" }
else
@title = "Sign up"
render 'new'
end
end
def edit
@title = "Edit user"
end
def update
if @user.update_attributes(params[:user])
redirect_to @user, :flash => { :success => "Profile updated." }
else
@title = "Edit user"
render 'edit'
end
end
def destroy
@user.destroy
redirect_to users_path, :flash => { :success => "User destroyed." }
end
private
def correct_user
@user = User.find(params[:id])
redirect_to(root_path) unless current_user?(@user)
end
def admin_user
@user = User.find(params[:id])
redirect_to(root_path) if !current_user.admin? || current_user?(@user)
end
end
and sessions controller is as follows:
class SessionsController < ApplicationController
skip_before_filter :check_sign_in, :only => [:new, :create]
def new
@title = "Sign in"
end
def create
user = User.authenticate(params[:session][:email],
params[:session][:password])
if user.nil?
flash.now[:error] = "Invalid email/password combination."
@title = "Sign in"
render 'new'
else
sign_in user
redirect_back_or user
end
end
def destroy
sign_out
redirect_to root_path
end
end
Each user has many authentications and each authentication belongs to a user
class Authentication < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_many :authentications
.......
The following are the scenarios I considered:
- User is logged in and wants to connect with his twitter. ( Completed without errors)
-
User is already a registered user and wants to use twitter for signing in every time( Completed without errors)
-
User is not registered and wants to use twitter for authentication. If its basic authentication then it is done but I need to make the user enter few details like country, gender, department etc. This is where everything is goign wrong. I am able to create an authentication and escape him to the sign in form but when user is signed in from fb or twitter he should not have to enter the password fields. This is my problem. Could anyone please let me know of what I should be doing to get over this error. Thank you.
I do something similar in a recent application – using Omniauth for authentication and allowing multiple authentications per user. For your case 3.) I create the user and the authentication first; then send them to a specific form (not the signup form) for filling out the rest of their profile.
This ‘extra’ form only comes into play if the required fields are not complete, otherwise they get redirected to the user show page. Seems to work well for me.
Edit: replace your current username/password gubbins with the Omniauth Identiy strategy: https://github.com/intridea/omniauth-identity. This way you have all your authentication handled by Omniauth. Believe me, your life will be simpler if you take out your hand-made password authentication code and replace it with Omniauth identity.
For the avoidance of doubt, by having both Twitter and Identity strategies in place it means that you are giving your users a choice as to how they authenticate. They may use either Twitter or username/password to authenticate. Both get the same job done, however, if they use Twitter then you never see the password information (which is fine).