Ruby on rails 设计:手动加密密码,直接存储

Ruby on rails 设计:手动加密密码,直接存储,ruby-on-rails,devise,Ruby On Rails,Devise,我正在尝试从旧数据库迁移大量用户。为此,我使用activerecord导入并尝试将所有用户数据直接保存到DB(绕过用户模型) 我的问题是:我需要获取旧用户的纯文本密码,对其进行加密,然后直接存储到数据库中。我知道如何使用Desive生成密码,但我想知道是否有一种方法可以获得一个哈希密码,我可以直接存储到数据库中 希望做到: new_hashed_password = Devise.awesome_encrypting_method(old_user.password) 然后将“新的散列密码”直

我正在尝试从旧数据库迁移大量用户。为此,我使用activerecord导入并尝试将所有用户数据直接保存到DB(绕过用户模型)

我的问题是:我需要获取旧用户的纯文本密码,对其进行加密,然后直接存储到数据库中。我知道如何使用Desive生成密码,但我想知道是否有一种方法可以获得一个哈希密码,我可以直接存储到数据库中

希望做到:

new_hashed_password = Devise.awesome_encrypting_method(old_user.password)
然后将“新的散列密码”直接存储到数据库中,而无需通过模型。我在Desive里翻了翻,发现了这个:

def password_digest(password)
  ::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s
end
@@拉伸默认为10(lib/designe.rb:71),并且不会被我的初始值设定项覆盖

@@pepper默认为nil(lib/designe.rb:148),并且不会被我的初始值设定项覆盖

我想我可以手动重新创建password_digest(),但我想我缺少了Bcrypt的一些基本功能,因为即使设置password和strength,每次生成的哈希值都是不同的


有什么想法吗?谢谢你的帮助

假设您有一个mysql数据库,其中包含一个“users”表和一个“password”列 以及一个名为“user”的ActiveRecord模型类,该类被连接起来用于设计

在应用程序中创建ActiveRecord模型类 app/models/old_user.rb

OldUser < ActiveRecord::Base
  set_table :users
  establish_connection :database => "old_database", :user => "old user", :adapter => "mysql"
end
根据需要进行修改(确保您正在保存任何特定于应用程序的用户属性)


然后,
$rake migrate\u用户

好消息和坏消息

好消息: 以下操作用于手动创建用户密码

 pepper = nil
 cost = 10
 encrypted_password = ::BCrypt::Password.create("#{password}#{pepper}", :cost => cost).to_s
您可以在Desive初始值设定项中找到您的花椒和成本。使用DeVICE的“有效密码”方法确认了该方法

坏消息: 我试图避免使用“User.new(password:password.encrypted_password)”的全部原因都是因为速度。太慢了。对于导入任务的所有其他部分,我都故意避免了这一点

但事实证明,这里的主要成本不是实例化用户对象,而是BCrypt本身。当直接使用BCrypt时,速度几乎没有明显的提升,因为它是特意设计为缓慢的


我的最终答案是:吸起来,运行rake脚本,去找饮料。

你应该这样做:

password = 'the secret password'
new_hashed_password = User.new(:password => password).encrypted_password

这比直接使用BCrypt要好得多,因为它将如何从代码中生成密码抽象出来,使其更易于理解,并且不受如何设计加密密码的更改的影响。您的代码不应该,也没有理由知道这方面的任何信息。

另一种方法是:
User.new.send(:password\u digest,'xxx')
上面的其他答案对我都不起作用,所以我做了以下工作:

用户。有效密码?(普通密码)


您应该能够从github的Desive源中提取加密方法源。然后,您可以使用rake或其他工具编写自定义生成器,以在旧密码的基础上运行它。这就是我现在要找的。希望有人已经弄明白了…我认为Desive使用了一种盐来加密,而你的BCrypt呼叫没有。谢谢,Jacob。但这是直接使用用户模型-->我有几十万行,所以我试图直接进入数据库而不使用用户模型。“速度太慢了。”这是出于设计!密码加密必须很慢,因此很难用蛮力破解
User.new(password:password)。encrypted_password
方法更可取,因为它将密码加密从代码中抽象出来,使它更容易理解,并且不受Desive生成密码方式变化的影响。这似乎并没有给出与Desive相同的答案。我试着将成本改为10-13的几个值,但似乎无法匹配?天哪,谢谢。对Ruby一无所知,必须在DB中更改密码,并且能够在控制台中执行此操作。
password = 'the secret password'
new_hashed_password = User.new(:password => password).encrypted_password