Ruby on rails 使用design防止密码重用
我知道在用户创建密码的一段时间后强制密码过期不是Desive逻辑的一部分,我计划编写自己的代码来实现这一点 另外,强制用户不要重复使用最后一个X(在我的例子中是10)密码中的一个密码也需要手动编码 我的想法是,我将创建一个类似于user\u passwords表的东西,并在代码中使用逻辑来确保新密码与该用户的表中的任何密码都不匹配。同时,我会将新密码插入表中,除非该用户已有10条记录,这意味着我将用新值覆盖最旧的记录。表结构如下所示: 用户密码Ruby on rails 使用design防止密码重用,ruby-on-rails,devise,Ruby On Rails,Devise,我知道在用户创建密码的一段时间后强制密码过期不是Desive逻辑的一部分,我计划编写自己的代码来实现这一点 另外,强制用户不要重复使用最后一个X(在我的例子中是10)密码中的一个密码也需要手动编码 我的想法是,我将创建一个类似于user\u passwords表的东西,并在代码中使用逻辑来确保新密码与该用户的表中的任何密码都不匹配。同时,我会将新密码插入表中,除非该用户已有10条记录,这意味着我将用新值覆盖最旧的记录。表结构如下所示: 用户密码 用户id 加密密码 创建于 如果有人有更好、更
- 用户id
- 加密密码
- 创建于
。。。创建类似于user_passwords表的内容,并在我的代码中使用逻辑来确保新密码与该用户在该表中的任何密码都不匹配 一旦你读了这一章,我就会问:为什么你首先允许用户选择一个脆弱/受伤/损坏的密码?这些60 KB的Bloom过滤器在与以下各项结合使用时看起来非常有用:)
防止密码重复使用 将要受到伤害的重用是跨站点的密码重用。Brown、Bracken、Zoccoli和Douglas表示,这一数字在《应用认知心理学》第18卷第6期第641-651页中约占70%。Das、Bonneau、Caesar、Borisov和Wang报告的数字在2010年约为45%。请注意,混乱的网络研究必须破解密码,因此这个数字可能更高,因为他们无法恢复所有密码 根据Das、Bonneau、Caesar、Borisov和Wang-in的说法,为了使重用成为一个更严重的问题,用户必须记住大约25个不同站点的密码 几年前我甚至被这个烫伤了。我在两个低值帐户上使用了相同的密码。然后遭到黑客攻击,攻击者能够使用恢复的密码来破坏一个很少使用的电子邮件帐户
现在,当我需要凭证时,我只生成一个长的随机字符串。我甚至不用为大多数网站写下它们。当我需要再次访问某个站点时,我只需执行恢复过程。在rails 5中,Desive_security_扩展不适用于我,我创建了我的自定义:
- 创建迁移并添加额外的列,如: 添加列:用户,:旧密码,:文本
- 在您的模型中添加两个回调:保存后:缓存旧过程和保存前:验证旧过程
- 创建回调的方法:
private def verify_old_pass if self.encrypted_password_changed? old_passwords.to_s.split(',').each do |pass_encrypted| if Devise::Encryptor.compare(self.class, pass_encrypted, password) errors.add(:base, 'Your password cannot be previous up to 3 back') return throw(:abort) end end end end def cache_old_pass # cache last 3 passwords if self.encrypted_password_changed? update_column(:old_passwords, ([self.encrypted_password] + old_passwords.to_s.split(',')[0, 3]).join(',')) end end
class PasswordsController < Devise::PasswordsController
def update
current_user = User.with_reset_password_token(params[:user][:reset_password_token])
if current_user && previous_and_new_password_is_same?(current_user)
current_user.errors[:password] << "has been used previously."
self.resource = current_user
respond_with resource
else
super
end
end
private
def previous_and_new_password_is_same?(current_user)
bcrypt = ::BCrypt::Password.new(current_user.encrypted_password)
hashed_value = ::BCrypt::Engine.hash_secret([params[:user][:password], Devise.pepper].join, bcrypt.salt)
hashed_value == current_user.encrypted_password
end
end
类密码控制器 当前用户错误[:密码]我认为“不要使用最近10个密码中的任何一个”有点武断,除非你有具体的商业原因。您可以轻松强制执行“不要使新密码与旧密码相同”。事实上,密码很难记住,而你要做的是让用户在便笺上写下密码。这是客户的实际要求。这是一家金融公司。那么,我认为没有比你提出的更优雅的解决方案了……我发现:太棒了。用这个回答你自己的问题!我想覆盖session_limitable行为,因为我只需要http请求的行为。任何想法…告诉我们你没有保存加密或不加密的实际密码,那将是完全不负责任的。当攻击者获得DB时,他也将获得加密密钥。这不是保存未加密的密码,而是保存由Desive生成的历史密码并由Desive验证(没有黑客攻击),因此我猜Desive::Encryptor的名称有误,因为它似乎执行哈希而不是加密-这是个好消息。这将是很好的,如果解释到底发生了什么,但我猜你付出了什么。不好的命名应该受到惩罚,但我们只是编码猴子,而不是专业人士。不幸的是,密码恢复过程是穷人的双重身份验证。