我正在考虑从 Devise 1.4.7 迁移到 Omniauth 1.0(使用“身份”策略或 gem),我的问题是在完成所有代码转换、 View 等之后,旧密码、那些用户帐户会保留吗?使用 Devise 创建的,在 OmniAuth 下仍然可以使用相同的密码吗?
我做了一些研究,两者都在使用 bcrypt,所以我猜“是的”它们会像以前一样工作,并且用户不必创建新密码。或者我错过了一些重要的东西?
最佳答案
设备密码不直接与omniauth-identity兼容
确实,它们都使用 bcrypt 来哈希密码,但是 Devise 在密码中添加了“胡椒”。您必须向omniauth-identity 添加代码以支持“pepper”。
- OmniAuth-Identity - lib/omniauth/identity/secure_password.rb
- 设计 - lib/devise/models/database_authenticatable.rb
记住你的密码
Devise 会在您的密码中添加胡椒(因为它已经被 bcrypt 加盐),因此为了将 devise 用户迁移到omniauth-identity,您必须教导身份策略如何为密码添加胡椒。这个片段对我们有用,但是我们没有更改 devise 中的 :stretches 配置选项。
# snatch the pepper setting from the devise initializer
pepper = "biglonguglystringfromyourdeviseinitializer"
# password created by devise in your db (i.e. "my_password_123")
encrypted_password = "$2a$10$iU.Br8ZClxuqldJt8Evl5OaBbHPJeBWbGV/1RoUsaNIZMBo8wHYTq"
# pepper the password then compare it using BCrypt like identity does
BCrypt::Password.new(encrypted_password) == "my_password_123#{pepper}"
=> true
我们如何让它发挥作用
这是一个非常快速且肮脏的猴子补丁,我们用来让它工作。我们正在研究如何以更合适的方式添加此功能。
# file: ~/railsapp/config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :identity
end
module OmniAuth
module Identity
module SecurePassword
module InstanceMethodsOnActivation
# Returns self if the password is correct, otherwise false.
def authenticate(unencrypted_password)
pepper = "the big pepper string from the devise initializer"
if BCrypt::Password.new(password_digest) == "#{unencrypted_password}#{pepper}"
self
else
false
end
end
# Encrypts the password into the password_digest attribute.
def password=(unencrypted_password)
pepper = "the big pepper string from the devise initializer"
@password = unencrypted_password
unless unencrypted_password.empty?
self.password_digest = BCrypt::Password.create("#{unencrypted_password}#{pepper}")
end
end
end
end
end
end
关于ruby-on-rails-3.1 - 从 dev 迁移到omniauth(身份),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9185353/