Laravel中自定义哈希后Auth::attempt返回false如何解决
根因说明
- Laravel 内置的
Auth::attempt()方法默认会自动将传入的password字段明文值用框架自带的哈希规则(bcrypt/argon)做哈希运算,再和数据库中存储的用户密码哈希值做比对。你提前用自定义hashPass()方法处理了密码之后再传入attempt(),相当于框架会对已经哈希后的字符串再做一次哈希,和数据库存储的值必然不匹配,所以始终返回false。 - 如果你的数据库存储的用户密码本身就是用
hashPass()生成的,没有使用Laravel默认哈希规则,那么默认认证驱动无法识别你的自定义哈希逻辑,也会导致校验失败。
解决方案
分两种场景处理:
场景1:数据库存储的密码为Laravel默认哈希生成
你无需手动处理密码哈希,直接把用户输入的明文密码传给Auth::attempt()即可,修改后代码如下:
public function login(Request $request) { $credentials = $request->validate([ 'email' => 'required|email:dns', 'password' => 'required' ]); // 移除提前调用hashPass处理密码的代码 if (Auth::attempt($credentials)) { $request->session()->regenerate(); return redirect()->intended('/dashboard')->with('loginSuccess', 'Login Berhasil'); } return back()->with('loginError', 'Login Gagal!'); }
场景2:数据库存储的密码为自定义hashPass方法生成,需要保留自定义哈希逻辑
有两种实现方案可选:
方案A:手动校验后直接登录用户(最简单)
绕过Auth::attempt()的自动校验逻辑,自己根据邮箱查询用户,手动比对密码后调用Auth::login()完成登录:
public function login(Request $request) { $credentials = $request->validate([ 'email' => 'required|email:dns', 'password' => 'required' ]); $user = \App\Models\User::where('email', $credentials['email'])->first(); // 手动用自定义方法校验密码 if ($user && hashPass($credentials['email'], $credentials['password']) === $user->password) { Auth::login($user); $request->session()->regenerate(); return redirect()->intended('/dashboard')->with('loginSuccess', 'Login Berhasil'); } return back()->with('loginError', 'Login Gagal!'); }
方案B:自定义哈希驱动适配框架认证逻辑
如果需要继续使用Auth::attempt()方法,可以自定义哈希驱动让框架适配你的哈希规则:
- 新建自定义哈希类实现
Illuminate\Contracts\Hashing\Hasher接口:
// app/Hashing/CustomHasher.php namespace App\Hashing; use Illuminate\Contracts\Hashing\Hasher; class CustomHasher implements Hasher { public function make($value, array $options = []) { $email = request()->input('email'); return hashPass($email, $value); } public function check($value, $hashedValue, array $options = []) { $email = request()->input('email'); return hashPass($email, $value) === $hashedValue; } public function needsRehash($hashedValue, array $options = []) { return false; } }
- 在
AppServiceProvider的boot方法中注册自定义哈希驱动:
// app/Providers/AppServiceProvider.php public function boot() { $this->app->bind('hash', fn () => new \App\Hashing\CustomHasher); }
注册完成后原有代码无需修改,Auth::attempt()就可以正常用自定义哈希规则做校验。
内容的提问来源于stack exchange,提问作者Muhammad Anang Ramadhan
相关产品推荐
相关产品推荐

