让 Rails 3.1 的 has_secure_password 与 OmniAuth 良好配合
我正在将一个项目从 Rails 3 移植到 3.1。我的身份验证系统很容易切换到 ActiveRecord 中新的 has_secure_password。我遇到的唯一问题是我也使用 OmniAuth,并且我已经设置了系统,因此如果用户使用 OmniAuth 提供商之一进行注册,则帐户不应需要密码。我似乎无法覆盖 has_secure_password 的password_digest 验证设置。是否有办法关闭这些验证并编写我自己的验证,或者我是否必须使用我的 Rails 3 版本站点中的旧手写 bcrypt 函数?
I'm porting a project from Rails 3 to 3.1. My authentication system was easily switched over to the new has_secure_password in ActiveRecord. The only problem I'm running into is that I also use OmniAuth and I have the system set up so if a user signs up using one of the OmniAuth providers the account shouldn't require a password. I can't seem to override the password_digest validations setup by has_secure_password. Is there anyway to turn off those validations and write my own, or am I going to have to just use my old hand written bcrypt functions from my Rails 3 version of the site?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
斯科特,你的想法是正确的。我一直在努力解决这个问题,但没有成功。我尝试覆盖“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 方法。
感谢您提出的想法。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我最终又回到使用自定义方法。然而,我后来确实意识到,我应该能够使用 before_validation 回调来检查条件,然后如果它们匹配,则将 password_digest 设置为任何简单的内容,例如“0”。这样,摘要就永远不会为空,但同时它不应该被验证为正确的密码,从而使他们通过 OmniAuth 登录。
如果我错了,请随时纠正我。
I ended up going back to using custom methods. However, I did realize afterwards that I should've been able to use a before_validation callback to check the conditions, then if they matched set the password_digest to anything simple like '0'. This way the digest would never be blank, but at the same time it shouldn't ever validate as a correct password, making them sign in through OmniAuth.
Feel free to correct me if I'm mistaken.