使用新的Omniauth方法登录现有用户

时间:2019-01-28 23:14:01

标签: ruby-on-rails

如果用户已使用“本地”电子邮件注册在我的网站上注册,然后注销,则希望使用其Facebook登录,我希望这很好,并“组合”信息整合到一个用户中。这是我这样做的方法:

  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

尽管我的测试非常简单,但它似乎工作正常。我只是有几个问题,是一个相对业余的程序员,并且赞赏那些有经验的人的智慧,他们不仅知道“如何”,而且知道“如何最好”。

  1. 这是常见的“合法”做法吗?我可能没有想到某些隐私或“最佳做法”问题?

  2. 是否有一种方法可以合并find_by语句的两个分支createif/elsif调用?实际上,this post在使用tap方面有很好的答案。有什么理由不这样做吗?

  3. 与多个提供者进行此操作的通常方法是什么(例如,如果我们正在谈论的用户是谁注册了电子邮件,然后使用Facebook登录,然后使用Google登录)?我最好的猜测是哈希或整个其他ActiveRecord对象。 (您甚至可以将哈希存储为ActiveRecord对象的属性吗?)

我希望可以发布并非完全是问题的问题。感谢您的建议!

1 个答案:

答案 0 :(得分:1)

1 )我已经完成了您所做的事情,从主题上看这不是问题。随着用户群的增长,让两个用户使用同一封电子邮件可能会很麻烦。

2 ),您可以使用find_or_create_by,即:

 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

请参见docs

3 )ActiveRecord支持将hash存储在列中。 https://api.rubyonrails.org/classes/ActiveRecord/Store.html详细说明了如何实现。