简体   繁体   中英

Omniauth-facebook & Devise: if email exists

I'm using omniauth-facebook and devise for authentication in my rails 4 app. I would like for a user, that already has authenticated through devise, also be able to add facebook auth later if they choose.
I would like to figure out how to check if the email of the devise logged user matches that of a facebook user, and if yes, add the uid and provider to that registered user.

Currently, I am getting the devise error message: " Email has already been taken "

User.rb

def self.from_omniauth(auth)
  where(auth.slice(:provider, :uid)).first_or_create do |user|
    user.provider = auth.provider
    user.uid = auth.uid
    user.name = auth.info.name
    user.username = auth.info.username
    user.email = auth.info.email
    user.oauth_token = auth.credentials.token
    user.oauth_expires_at = Time.at(auth.credentials.expires_at)      
  end
end

def self.new_with_session(params, session)
  if session["devise.user_attributes"]
    new(session["devise.user_attributes"], without_protection: true) do |user|
      user.attributes = params
      user.valid?
    end
  else
    super
  end
end

Controller:

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def all
    #render :text => "<pre>" + env["omniauth.auth"].to_yaml and return
    user = User.from_omniauth(request.env["omniauth.auth"])
    if user.persisted?
      #session[:user_id] = user.id # for current_user
      flash.notice = "Signed in!"
      sign_in_and_redirect user
    else
      session["devise.user_attributes"] = user.attributes
      redirect_to new_user_registration_url
    end
  end
  alias_method :facebook, :all
end

Thanks!!!!

I just had the same problem and used this code to solve it.

It first checks if the email exists in the database and if it does it updates the uid and the provider fields, if not I create a new user with the auth params. In the end I just return the variable return_user and the flow works as normal.

def self.from_omniauth(auth)
  if self.where(email: auth.info.email).exists?
    return_user = self.where(email: auth.info.email).first
    return_user.provider = auth.provider
    return_user.uid = auth.uid
  else
    return_user = self.create do |user|
       user.provider = auth.provider
       user.uid = auth.uid
       user.name = auth.info.name
       user.username = auth.info.username
       user.email = auth.info.email
       user.oauth_token = auth.credentials.token
       user.oauth_expires_at = Time.at(auth.credentials.expires_at) 
    end
  end

  return_user
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM