我开始研究一个已经有很多代码的项目。这是一个使用Devise进行用户认证的Ruby on Rail应用程序。该应用程序的一个要求是,当用户更改密码时,不允许使用与之前使用的最后三个密码相同的密码。为了实现这一点,有一张表包含给定用户的密码历史记录。这些密码是在用户更改密码之前存在的加密密码的副本。加密密码以匹配存储的加密密码。
这是问题出现的地方。我们有一个密码更改表单,用于收集给定用户的新密码。我需要能够获取新密码并对其进行加密,以便我可以将新密码的加密值与历史记录中旧密码的加密值相匹配。
技术性的东西
的Rails 3.0.9版本
设计版本1.3.4
使用标准BCrypt与设计。 bcrypt_ruby版本2.1.4
为此,我们重写了Devise支持的reset_password方法。这允许我们在用户控制器中引入我们自己的方法has_repeated_password。
has_repeated_password我开始用的版本低于:
def has_repeated_password?
return false if self.new_record? || self.version == 1
histories = self.versions.find(:all, :order => 'version DESC', :limit => 3)
histories.detect do |history|
history.encrypted_password == self.class.encryptor_class.digest(self.password, self.class.stretches, history.password_salt, self.class.pepper)
end
end
的这里的问题是,加密类是从来没有定义,每次导致错误该程序运行。即使有很多例子声称这是有效的,但当Devise使用默认加密时,我无法实现它。
在这方面的一个第二次尝试下面的代码:
def has_repeated_password?<br>
return false if self.new_record? || self.version == 1
histories = self.versions.find(:all, :order => 'version DESC', :limit => 3)
histories.detect do |history|
pwd = self.password_digest(self.password)
history.encrypted_password == pwd
end
end
在这种情况下,我从来没有得到任何匹配存储的密码的密码,即使我已经验证,在数据库中的密码我期望的。
我一直试图挖掘设计代码,看看我能在那里找到。我知道,当它将从用户收集的密码与存储的密码进行匹配时,认证必须以某种方式执行此操作。
任何帮助,将不胜感激。
使用'p = BCrypt :: Password.new(history.encrypted_password)'然后'p == password'更正确。 'BCrypt :: Password'类有'=='操作符定义。 –