获取Rails 3.1的has_secure_password可以很好地与OmniAuth配合使用

时间:2011-09-21 02:07:59

标签: ruby-on-rails-3.1 omniauth

我正在将项目从Rails 3移植到3.1。我的身份验证系统很容易切换到ActiveRecord中的新has_secure_password。我遇到的唯一问题是我也使用OmniAuth并且我已经设置了系统,因此如果用户使用其中一个OmniAuth提供商注册,则该帐户不需要密码。我似乎无法覆盖has_secure_password设置的password_digest验证。无论如何要关闭那些验证并编写我自己的验证,或者我将不得不在我的Rails 3版本的网站上使用我手写的旧手写的bcrypt函数?

2 个答案:

答案 0 :(得分:5)

我最终回到了使用自定义方法。但是,之后我确实意识到我应该能够使用before_validation回调来检查条件,然后如果匹配则将password_digest设置为任何简单的“0”。这样,摘要永远不会是空白,但同时它不应该验证为正确的密码,使它们通过OmniAuth登录。

如果我弄错了,请随时纠正我。

答案 1 :(得分:4)

斯科特,你的想法是正确的。我一直在努力解决这个问题无济于事。我试图覆盖'has_secure_password',它根本不起作用。无论我在哪里插入代码。

相反,我有以下内容:

class User < ActiveRecord::Base
  has_secure_password

  validates_presence_of :password, :on => :create, :if => :password_required

  # Associations
  has_many :authentications

  # Callbacks
  before_validation :no_password_omniauth

  # Gets set to true if the caller is trying to authenticate with omniauth.
  @called_omniauth = false

  # Build new omniauth users
  def apply_omniauth(omniauth)
    authentications.build(
    :provider => omniauth['provider'], 
    :uid => omniauth['uid'])
    self.first_name = omniauth['user_info']['first_name'] if self.first_name.blank?
    self.last_name = omniauth['user_info']['last_name'] if self.last_name.blank?
    self.email = omniauth['user_info']['email'] if omniauth['user_info']['email'] && self.email.blank?
    @called_omniauth = true
  end

  def password_required
    return false if @called_omniauth == true
    (authentications.empty? || !password.blank?)
  end

  private

  def no_password_omniauth
    self.password_digest = 0 unless password_required
  end

end

当有人尝试进行身份验证或注册时,会从控制器调用apply_omniauth方法。

感谢您提出的想法。