简体   繁体   中英

Logging in a pre-existing user with new Omniauth method

If a user has registered on my website using the "native" email registration, and then later, being logged out, wants to use their Facebook to log in, I want this to be just fine, and to "combine" the info into one user. Here is my method for doing so:

  def self.from_omniauth(auth)
    if user = User.find_by(email: auth.info.email)
      user.provider    ||= auth.provider
      user.uid         ||= auth.uid
      user.first_name  ||= auth.info.first_name   
      user.last_name   ||= auth.info.last_name   
      user.save
      user
    elsif user = User.create(provider: auth.provider, uid: auth.uid)
      user.email = auth.info.email
      user.password = Devise.friendly_token[0,20]
      user.first_name = auth.info.first_name   
      user.last_name = auth.info.last_name   
      user.save 
      user
    end
  end

It appears to work fine, though my tests are pretty simple. I just have a few questions, being a relatively amateur programmer and appreciating the wisdom of those with the experience to know not just "how to" but "how best to.

  1. Is this a common and "legit" practice? Is there maybe some privacy or "best practice" concern I'm not thinking of?

  2. Is there a way to combine the find_by and create calls, the two branches of my if/elsif statement? Actually, this post has a great answer in using tap . Is there any reason not to do that?

  3. What is the usual way to do this with more than one provider (like if the user we're talking about who has registered with email, then logged in with Facebook, then logs in with Google)? My best guess is either a hash or a whole other ActiveRecord object. (can you even store a hash as a property of an ActiveRecord object?)

I hope it's okay to post a question that isn't exactly a problem. Thanks for the advice!

1 )I have done what you did and don't think it's a problem subjectly. Having two users with same email can be a hassle to manage as user base grows.

2 )You can use find_or_create_by ie:

 def self.from_omniauth(auth)
   user = User.find_or_create_by(email: auth.info.email) do |u|
     u.provider = auth.provider
     u.uid = auth.uid
     ...
   end
 end

See docs

3 ) ActiveRecord supports storing hash in column. https://api.rubyonrails.org/classes/ActiveRecord/Store.html provides good details how you can achieve it.

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