Laravel 8中Auth::attempt()仅首个创建用户验证通过其余均返回false
问题解决方案
问题根因定位
你的代码存在3个核心问题,完全匹配「仅第一个用户可登录,后续用户登录Auth::attempt返回false」的表现:
- 注册逻辑的邮箱查重参数错误
你现有校验用户是否存在的代码查询的是请求参数email,但你整个注册、登录逻辑里接收用户输入的邮箱字段都是user_email,意味着$request->input('email')永远为null,该校验逻辑完全失效,极端情况下会出现同邮箱多用户、甚至邮箱字段存空值的情况,导致后续登录时无法匹配到正确的用户记录。 - 大概率存在密码重复Hash的情况
如果你在User模型中定义了setPasswordAttribute密码修改器,自动对传入的密码做Hash处理,那么你代码里手动调用Hash::make就会导致密码被两次Hash,存入数据库的是二次Hash后的结果,自然无法和登录时Auth::attempt一次Hash后的结果匹配。 - 注册后登录逻辑冗余
你注册成功后不需要调用Auth::attempt校验,已经拿到了合法的用户对象,直接登录即可,多余的校验逻辑反而会增加出错概率。
修复步骤
- 修正注册逻辑的邮箱校验代码,替换原有get查询为更高效的存在判断:
// 原有错误代码 // $user=User::where('email',$request->input('email'))->get(); // if($user->isEmpty()) // 替换为如下代码 if (!User::where('email', $request->input('user_email'))->exists()) {
- 检查User模型是否存在密码自动Hash的修改器,做对应调整:
- 如果存在
setPasswordAttribute修改器,删除注册代码里的手动Hash逻辑:
// 原有代码 // $password=Hash::make($request->input('user_password')); // $user->password=$password; // 替换为 $user->password = $request->input('user_password');- 如果不存在该修改器,保留原有Hash逻辑即可。
- 如果存在
- 替换注册成功后的attempt登录为直接登录,提升效率避免二次查询出错:
// 原有错误代码 // Auth::attempt(['email' => $request->input('user_email'), 'password' => $request->input('user_password')],true); // 替换为 Auth::login($user, true);
- 如果修复后仍有问题,可在登录逻辑中加临时调试代码定位问题:
public function doLogin(Request $request){ // 临时调试代码,确认参数和存储的哈希值匹配 $inputEmail = $request->input('user_email'); $inputPwd = $request->input('user_password'); $user = User::where('email', $inputEmail)->first(); if (!$user) { dd('邮箱不存在'); } if (!Hash::check($inputPwd, $user->password)) { dd('密码哈希不匹配'); } $login=Auth::attempt(['email'=>$inputEmail, 'password'=>$inputPwd],true); if($login) return redirect()->route('user_profile'); return redirect()->route('user_login'); }
内容的提问来源于stack exchange,提问作者Mokhtar Ghaleb
相关产品推荐
相关产品推荐

