Laravel实现邮箱/联系电话双登录时手机号无法登录的问题
Laravel 邮箱/联系号码双方式登录失效问题修复
核心问题原因
现有控制器的登录查询逻辑存在两处致命错误:
- 两个分支的判断条件都使用了
$request->username,第一个if ($request->username)触发后直接执行邮箱查询,后续else if ($request->username)的分支永远不会被执行,等于联系号码的查询逻辑完全没走到,自然手机号登录永远匹配不到对应用户。 - 原代码中
contact_no查询那行的换行格式错误,直接使用可能触发PHP语法解析问题。
修复方案
可根据实际场景选择两种实现逻辑:
方案1:根据输入内容格式走对应查询分支
先判断输入的账号属于邮箱格式还是手机号格式,再执行对应查询,适合两种字段格式差异较大的场景:
public function index(Request $request) { // 先校验请求参数合法性 $request->validate([ 'username' => 'required|string', 'password' => 'required|string', ]); $username = trim($request->username); // 判断是否为邮箱格式 if (filter_var($username, FILTER_VALIDATE_EMAIL)) { $user = User::where('email', $username)->first(); } else { // 非邮箱格式按联系号码查询,可按需补充号码格式预处理逻辑,比如去掉空格、区号等 $cleanContactNo = preg_replace('/[^0-9]/', '', $username); $user = User::where('contact_no', $cleanContactNo)->first(); } // 后续密码校验逻辑 if ($user && Hash::check($request->password, $user->password)) { $temp_login_code = Hash::make(Str::random(100)); $user->temp_login_code = $temp_login_code; $user->save(); $url = config('property.cms_login_url') . '?code=' . $temp_login_code; return redirect($url); } return redirect()->back()->with('error', '账号或密码错误'); }
方案2:直接同时查询两个字段(更简便)
不需要判断格式,直接用orWhere同时匹配邮箱和联系号码,适合快速开发场景:
public function index(Request $request) { $request->validate([ 'username' => 'required|string', 'password' => 'required|string', ]); $username = trim($request->username); $user = User::where('email', $username) ->orWhere('contact_no', $username) ->first(); if ($user && Hash::check($request->password, $user->password)) { $temp_login_code = Hash::make(Str::random(100)); $user->temp_login_code = $temp_login_code; $user->save(); $url = config('property.cms_login_url') . '?code=' . $temp_login_code; return redirect($url); } return redirect()->back()->with('error', '账号或密码错误'); }
额外注意事项
- 如果你的联系号码存储时带了区号、空格等格式,查询前一定要做对应的格式清洗,避免格式不匹配导致查不到用户。
- 原代码里给
$user赋值属性后调用$user->update()的写法不生效,update()需要传入要更新的数组参数,改用$user->save()更稳妥,可正常保存修改的字段。
内容的提问来源于stack exchange,提问作者zubair malik
相关产品推荐
相关产品推荐

