我们正在将我们的站点从旧的 PHP 框架转换为 Rails,并且真的希望用户能够继续使用他们的旧密码登录。在旧网站上,我们使用 password_hash 和 password_verify 来散列和验证密码。但是,在 Rails 上我似乎无法验证旧密码。
这是我们在 PHP 中的内容:
哈希:
password_hash($user['salt'] . $password . $user['salt'], PASSWORD_DEFAULT);
验证:
password_verify($user['salt'] . $password . $user['salt'], $user['password'])
在新的 Rails 框架上,我们使用 Devise 并构建了一个自定义迁移脚本来移动所有内容,并根据存储在数据库中的 password_version 识别正确的密码散列方法,这就是我在我的内部使用的用户模型:
def valid_password?(password)
if password_version == 'legacy'
hash = BCrypt::Password.new(encrypted_password)
hash_str = password_salt+password+password_salt
return hash.is_password? hash_str
end
super(password)
end
任何想法将不胜感激
最佳答案
PHP password_hash
密码的格式大致如下所示:
$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a
默认的 Ruby Bcrypt 方法生成以下形式的密码:
$2a$10$GtKs1Kbsig8ULHZzO1h2TetZfhO4Fmlxphp8bVKnUlZCBYYClPohG
对于此处的干净解决方案,您始终可以通过 $2y
或 $2a
前缀来区分两者。格式列已经包含在格式中时,就不需要格式列了。
例如:
case (encrypted_password[0,3])
when '$2y'
# Legacy PHP password
BCrypt::Password.new(encrypted_password.sub(/\A\$2y/, '$2a')).is_password?(salt + password + salt)
when '$2a'
# Ruby BCrypt password
BCrypt::Password.new(encrypted_password).is_password?(password)
else
# Unexpected type?
end
密码验证成功后要做的是使用Ruby的方法将密码重新写入数据库,逐步替换所有旧的PHP格式的密码。
关于php - 将 PHP 的 password_verify 转换为 Ruby on Rails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38983631/