我正在将一个旧的PHP应用程序迁移到Laravel 5.2 . 该应用程序有一个巨大的用户表(约50K用户),密码都是MD5哈希 .
显然这是不可接受的,而不是向所有50,000名用户发送电子邮件,要求他们重置密码,我想在后台将密码更改为bcrypt哈希 .
为此,我想在其中创建一个带有MD5哈希的 old_password
列,然后每当用户登录时,我都会根据MD5哈希(如果存在)检查密码,然后下次创建一个新的bcrypt哈希,删除MD5哈希 .
我已经看到了一些关于如何执行此操作的示例(例如this和this),但没有专门用于Laravel 5,也没有专门用于Laravel 5.2的内置身份验证 .
有没有一种干净的方法来调整内置的auth来做到这一点,或者我最好在这种情况下编写自己的手动auth系统?
4 回答
从Drupal迁移时我遇到了类似的问题 . 我没有为旧密码创建一个新列,但更新了hasher以检查密码Drupal-way然后如果失败,请使用bcrypt进行检查 . 这样老用户可以以与新用户相同的方式登录 .
您需要在app中的任何位置创建一个包,比如app / packages / hashing . 把这两个文件放在那里 .
YourHashingServiceProvider.php
YourHasher.php
然后将
App\Packages\Hashing\YourHashingServiceProvider::class
放在providers
中的config / app.class中 . 此时,您的旧用户应该能够登录您的laravel应用程序 .现在,要在用户控制器(登录/注册表单)中的某个位置更新其密码,您可以使用
Hash::needsRehash($hashed)
和Hash::make($password_value)
为用户生成新的bcrypt密码,然后保存 .在Laravel 5.2中,您的 AuthController.php 应该覆盖登录方法,只需添加以下内容即可 .
登录失败时,它会尝试使用md5()登录用户 .
基于我在sustainable password hashing上读到的一篇文章,我对解决方案的解决方法与@neochief略有不同,特别是元算法的底部位 .
我分3步完成了这个步骤:
通过将md5密码包装在bcrypt中,将bcrypt应用于数据库中的所有用户密码,就好像它们是纯文本一样
当用户尝试进行身份验证时,使用
guard->attempt(...)
单独使用bcrypt . 如果身份验证失败,则使用md5对请求中发送的密码进行双重加密,然后尝试使用guard->attempt(...)
重新进行身份验证,然后将md5包装在bcrypt中进行比较 .经过身份验证后,只使用bcrypt存储纯文本密码,因此双重加密不必同时应用于同一用户 .
我将AuthenticatesUsers :: login引入AuthController以使用我自己的逻辑覆盖逻辑,并调用一个包含登录尝试逻辑的受保护方法 . 我正在使用JWT-Auth,但如果你不是你的解决方案将没有太大的不同 .
希望这对某人有用 .
我将@Leonardo Beal的AuthController更新为Laravel 5.6 .
我将我的应用程序从Laravel 4.2迁移到5.6,这就像一个魅力(添加到app / Http / Controllers / Auth / LoginController.php):