I’m using Rails, Devise, and Omniauth, and I’m trying to login using facebook connect.
But after the facebook part, I’m being redirected to ‘/users/sign_in#=‘ in my application.
According to the log (see the code), the user is persisted, so this callback is calling the sign_in_and_redirect method:
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def facebook
# You need to implement the method below in your model
@user = User.find_for_facebook_oauth(request.env["omniauth.auth"], current_user)
if @user.persisted?
logger.debug "User #{@user.email} is persisted"
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
sign_in_and_redirect @user, :event => :authentication
else
logger.error "User #{@user.email} is not persisted"
session["devise.facebook_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
end
What could be going wrong?
Note: I’m using MongoID, dunno if that matters. The user is being added correctly to the DB.
UPDATE: I have just noticed that Devise is sending me an email to confirm my registration, even when I’m using facebook to authenticate. Maybe this is the problem? How to make the user model :confirmable, except when authenticating with facebook? Is that possible? Here is my User model:
class User
include Mongoid::Document
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable, :omniauthable
## Database authenticatable
field :email, :type => String, :null => false, :default => ""
field :encrypted_password, :type => String, :null => false, :default => ""
## Recoverable
field :reset_password_token, :type => String
field :reset_password_sent_at, :type => Time
## Rememberable
field :remember_created_at, :type => Time
## Trackable
field :sign_in_count, :type => Integer, :default => 0
field :current_sign_in_at, :type => Time
field :last_sign_in_at, :type => Time
field :current_sign_in_ip, :type => String
field :last_sign_in_ip, :type => String
## Encryptable
# field :password_salt, :type => String
## Confirmable
field :confirmation_token, :type => String
field :confirmed_at, :type => Time
field :confirmation_sent_at, :type => Time
field :unconfirmed_email, :type => String # Only if using reconfirmable
## Lockable
# field :failed_attempts, :type => Integer, :default => 0 # Only if lock strategy is :failed_attempts
# field :unlock_token, :type => String # Only if unlock strategy is :email or :both
# field :locked_at, :type => Time
## Token authenticatable
# field :authentication_token, :type => String
def self.find_for_facebook_oauth(access_token, signed_in_resource=nil)
data = access_token.extra.raw_info
if user = User.where(:email => data.email).first
user
else # Create a user with a stub password.
User.create!(:email => data.email, :password => Devise.friendly_token[0,20])
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
user.email = data["email"]
end
end
end
end
I took the code from the devise/omniauth docs: https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
Had to change the find_for_facebook_oauth method to skip confirmation
Now it works, but it’s still adding garbage to the URL. I’m being redirected to ‘/#=‘, which shows the home page. I’m gonna post another question for this.