laravel的auth登录默认使用email作为登录账号,但平时使用的时候可以会涉及到多个字段作为登录账号的情况,如phone,name,email
auth的登录控制器是 app/Http/Auth/LoginController.php,在这里,我们可以看到
17e2a933-b45d-4a19-81c3-f73dd39145a8.png
登录基本的操作都在这个 AuthenticatesUsers 里面。进入AuthenticatesUsers,可以看到有个login的方法,基本逻辑都在这个方法里面
public function login(Request $request)
{
//数据的验证方法
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and // the IP address of the client making these requests into this application.
//登录次数过多的时候
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
//账号密码验证成功后进入此方法
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this // user surpasses their maximum number of attempts they will get locked out.
//应该是登录失败时的失败次数和时间记录
$this->incrementLoginAttempts($request);
//账号密码验证不通过时返回的错误信息方法
return $this->sendFailedLoginResponse($request);
}
本来可以通过在loginController.php里面重写 attemptLogin 方法来实现多字段登录,但由于数据验证方法 validateLogin 在前面,重写 attemptLogin 的话会使验证时一些字段失效,所有可以重写 validateLogin 方法
protected function validateLogin(Request $request)
{
$username = $request->post('username');
//邮箱的正则
$emailPattern = "/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/i";
//检验输入用户账户的格式
if(preg_match("/^1[3456789]\d{9}$/",$username)){
$this->field = 'phone';
}elseif(preg_match($emailPattern,$username)){
$this->field = 'email';
}else{
$this->field = 'name';
}
$request[$this->field] = $username;
$request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
]);
}
同时需要给loginController控制器加一个属性 private $field = 'name'
和重写 username()
方法
public function username()
{
return $this->field;
}
前端blade文件的处理
我们在重写 validateLogin 方法时用的是username,所以前端文件的账号输入框的name属性也要相应修改
<input id="email" type="text" class="form-control @error('email') is-invalid @enderror name="username" value="{{ old('username') }}" required autocomplete="username" autofocus>
但原来显示错误信息的默认 email ,所以还有增加phone和name的错误显示和placeholder提醒
<input id="email" type="text" class="form-control @error('email') is-invalid @enderror @error('name') is-invalid @enderror @error('phone') is-invalid @enderror" name="username" value="{{ old('username') }}" required autocomplete="username" placeholder="用户名/手机号/邮箱" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>@enderror
@error('phone')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>@enderror
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>@enderror
这样错误信息才能正确显示
用户名登录错误
image.png
邮箱登录错误
image.png
手机号登录错误
image.png