如何在Laravel中验证bcrypt密码?修改密码旧密码验证方案
解决Laravel中旧密码与bcrypt加密密码对比的验证问题
这个问题我之前也碰到过,核心原因是你用的exists:users,password规则是直接拿提交的明文密码去数据库里匹配加密后的字段,这肯定对不上——毕竟bcrypt加密后的字符串和明文完全不一样,而且每次加密同一段明文结果都不同。下面给你两种靠谱的解决方法:
方法一:控制器内手动验证(快速实现)
先做基础的字段规则验证,再单独用Laravel的Hash门面对比旧密码和用户存储的加密密码:
use Illuminate\Support\Facades\Hash; public function updatePassword(Request $request) { // 先验证字段格式(注意修正新密码的规则写法:用|分隔而不是:) $validated = $request->validate([ 'old_password' => 'required|min:6', 'password' => 'required|min:6|max:30|confirmed', // 加confirmed可以让用户输入两次新密码确认,更安全 ]); // 对比旧密码是否正确 if (!Hash::check($request->old_password, auth()->user()->password)) { // 返回错误提示,指定old_password字段的错误信息 return back()->withErrors(['old_password' => '密码不匹配']); } // 旧密码正确,更新新密码 auth()->user()->update([ 'password' => Hash::make($request->password) ]); return back()->with('success', '密码修改成功'); }
方法二:自定义验证规则(复用性强)
如果这个验证逻辑在多个地方用到,自定义规则会更优雅:
- 在
app/Providers/AppServiceProvider.php的boot方法里注册自定义规则:
use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Hash; public function boot() { Validator::extend('current_password', function ($attribute, $value, $parameters, $validator) { // 对比提交的明文和当前用户的加密密码 return Hash::check($value, auth()->user()->password); }); }
- 然后在控制器的验证规则里直接使用这个自定义规则:
$this->validate($request, [ 'old_password' => 'required|min:6|current_password', 'password' => 'required|min:6|max:30|confirmed', ], [ // 自定义错误提示 'current_password' => '密码不匹配', ]);
关键注意点
- 不要用
exists规则验证密码:bcrypt加密的特性决定了不能直接用明文匹配数据库字段,必须用Hash::check()方法。 - 修正新密码的规则:你原来写的
min:6:max:30是错误的,Laravel的验证规则之间要用竖线|分隔,正确写法是min:6|max:30。
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

