Laravel 5.4中使用Auth实现邮箱/手机号二选一的登录验证
实现「邮箱/手机号 + 密码」的Auth验证逻辑
你的问题出在Auth::check()的参数逻辑上——它会把你传入的email、mobile和password当作AND条件去匹配,也就是要求用户的邮箱和手机号同时等于输入值,这显然不符合「邮箱或手机号」的需求。下面给你两种简洁的解决方案:
方案一:先查询用户再验证密码
这种方式更直观,先根据输入值找到对应的用户,再单独验证密码是否正确:
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use App\Models\User; // 根据输入值匹配邮箱或手机号,找到对应的用户 $user = User::where('email', $request->email) ->orWhere('mobile', $request->email) ->first(); // 验证用户存在且密码匹配 if ($user && Hash::check($request->password, $user->password)) { // 手动登录用户 Auth::login($user); return Auth::user(); } // 验证失败返回错误 return response()->json(['message' => '邮箱/手机号或密码错误'], 401);
方案二:动态构建认证凭据
利用Auth::attempt()方法,根据输入内容的类型(邮箱/手机号)动态构建凭据数组,让Laravel帮你处理认证:
use Illuminate\Support\Facades\Auth; // 初始化凭据,先放入密码 $credentials = ['password' => $request->password]; // 判断输入值是邮箱还是手机号,添加对应字段到凭据 if (filter_var($request->email, FILTER_VALIDATE_EMAIL)) { $credentials['email'] = $request->email; } else { // 这里可以额外添加手机号格式验证,比如正则匹配国内手机号 if (preg_match('/^1[3-9]\d{9}$/', $request->email)) { $credentials['mobile'] = $request->email; } else { return response()->json(['message' => '手机号格式不正确'], 400); } } // 执行认证 if (Auth::attempt($credentials)) { return Auth::user(); } // 认证失败 return response()->json(['message' => '邮箱/手机号或密码错误'], 401);
额外注意事项
- 确保你的
User模型中包含email和mobile字段,且两个字段都设置了唯一约束(避免重复数据导致匹配异常)。 - 存储用户密码时,一定要用
Hash::make()进行加密,否则Hash::check()和Auth::attempt()都会验证失败。 - 如果需要支持更多登录方式,可以扩展这个逻辑,比如加入用户名匹配。
内容的提问来源于stack exchange,提问作者Sandip Nag
相关产品推荐
相关产品推荐

