Laravel5.4多字段登录
最近在一个项目中需要实现一个多字段登录功能,就是可以使用用户名、邮箱或手机号任意一种方式进行登录。
以下内容基于laravel5.4
首先,通过artisan
工具生成auth模块
php artisan make:auth
这时候App\Http\Controllers
目录下会新增一个Auth
目录,该目录下为注册登录相关的控制器,resources\views
目录下也会生成一些与注册登录相关的视图
laravel的官方文档中说手动认证用户需要使用Illuminate\Support\Facades\Auth
类的attempt方法,如下:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
/**
* Handle an authentication attempt.
*
* @return Response
*/
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
}
这个方法会根据你传入的参数判断数据库中是否存在与之相匹配的用户,如果存在并且密码正确返回true
,反之返回false
遂在LoginController
中添加该方法,但是好像并没有效果
于是开始观察LoginController
的实现机制,发现它实现了一个AuthenticatesUsers
的trait
,追踪到这个trait
的定义文件,发现这个文件就是我们想要的东西
里面有一个login
方法,就是负责处理登录的逻辑
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response
*/
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.
// 防止暴力破解,多次登录失败会根据IP锁定
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
// 这个就是主要的负责判断数据库中是否存在相应的账号和密码的地方,我们需要重写的就是attemptLogin方法
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);
}
分析了一波这个文件,发现主要进行登录判断的就是attemptLogin
方法,我们只要重写这个方法即可,先看看原来的是怎么写的,根据原来的进行重写:
/**
* Attempt to log the user into the application.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function attemptLogin(Request $request)
{
return $this->guard()->attempt(
$this->credentials($request), $request->has('remember')
);
}
在LoginController重写后:
public function attemptLogin(Request $request)
{
$username = $request->input('username');
$password = $request->input('password');
// 验证用户名登录方式
$usernameLogin = $this->guard()->attempt(
['username' => $username, 'password' => $password], $request->has('remember')
);
if ($usernameLogin) {
return true;
}
// 验证手机号登录方式
$mobileLogin = $this->guard()->attempt(
['mobile' => $username, 'password' => $password], $request->has('remember')
);
if ($mobileLogin) {
return true;
}
// 验证邮箱登录方式
$emailLogin = $this->guard()->attempt(
['email' => $username, 'password' => $password], $request->has('remember')
);
if ($emailLogin) {
return true;
}
return false;
}
只需要用attempt
方法进行多次判断即可,只要成功就返回true
,不成功继续用其他字段进行判断,都不成功则返回flase
测试,可以实现多字段登录效果