Laravel默认只允许用户使用其电子邮件地址登录。现在,如果要让您的用户使用电子邮件甚至用户名登录,该怎么办?
为此,您只需要更改Laravel默认身份验证代码中的某些代码即可。
开始吧。我认为您已经设置了Laravel项目并迁移了Laravel默认身份验证。如果您还没有编写命令php artisan make:auth
,那么请执行php artisan migrate
。
上面的命令使Laravel为您提供基本和默认身份验证,因此您不必手动制作登录,注册,忘记密码和重置密码。
步骤
打开loginController.php
默认情况下,您只会在登录控制器中看到这些代码
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
该控制器仅具有属性和一个构造函数,那么它如何处理登录功能?在这里OOP
发挥作用。
注意这里的use AuthenticatesUsers;
声明,这是Laravel构建其默认登录功能的地方。现在,让我们检查一下AuthenticateUsers
类。
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
trait AuthenticatesUsers
{
use RedirectsUsers, ThrottlesLogins;
/**
* Show the application's login form.
*
* @return \Illuminate\Http\Response
*/
public function showLoginForm()
{
return view('auth.login');
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*
* @throws \Illuminate\Validation\ValidationException
*/
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);
}
/**
* Validate the user login request.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function validateLogin(Request $request)
{
$request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
]);
}
/**
* 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->filled('remember')
);
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
return $request->only($this->username(), 'password');
}
/**
* Send the response after the user was authenticated.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
}
/**
* The user has been authenticated.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function authenticated(Request $request, $user)
{
//
}
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
return 'email';
}
/**
* Log the user out of the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->invalidate();
return $this->loggedOut($request) ?: redirect('/');
}
/**
* The user has logged out of the application.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
protected function loggedOut(Request $request)
{
//
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard();
}
}
如果您是初学者,并且刚接触OOP
世界,那么在看这些代码行时,您可能会觉得不知所措。但是不要。现在,我们在处理登录功能的类中进行了查看,现在您的问题可能是“我们如何自定义它以满足我们的需求?”
好吧,你不!请记住,“ AuthenticateUsers”类的位置Illuminate\Foundation\Auth\AuthenticatesUsers
在Vendor
目录下。不要编辑或更改此类中的任何内容,否则您的Composer会感到烦恼!
Laravel是一个Object-Oriented
框架。因此,我们正在应用重写的OOP方法。
我们希望我们的应用程序允许用户使用电子邮件或用户名登录,因此让我们看一下处理该部分内容的方法AuthenticateUsers
。您可能已经注意到,此方法username()
描述了它的作用。
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
return 'email';
}
上面的注释告诉我们,它将email
作为控制器使用的登录用户名返回。现在,这是我们必须重写的方法。
复制该username()
方法并将其粘贴到您的计算机中loginController.php
。现在,代替返回email
,我们需要返回email
和username
。
现在这是我们必须检查登录表单的部分。在我们的默认登录表单中,查找默认的电子邮件输入,并将名称从更改name="email"
为name="identity"
。稍后,它将identity
作为HTTP请求发送到我们的Laravel。
再次回到username()
方法,我们需要实现一种方法来检查email
以电子邮件地址或用户名形式出现的HTTP请求。我们可以通过检查发送的数据中是否有“ @”来做到这一点。幸运的是,PHP建立了一个函数来执行此操作。如果有一个“ @”,则HTTP请求email
确实是一个电子邮件地址。否则,它是一个用户名。
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
$login = request()->input('identity');
$field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
request()->merge([$field => $login]);
return $field;
}
上面的代码的作用是使用来过滤出现@或电子邮件的HTTP请求FILTER_VALIDATE_EMAIL
。如果是电子邮件,则返回email
,否则,返回username
。
完成此操作后,我们只剩下一个要做的事情,那就是覆盖验证请求。在您的登录控制器类中,在下面添加以下代码:
/**
* Validate the user login request.
*
* @param \Illuminate\Http\Request $request
* @return void
*
* @throws \Illuminate\Validation\ValidationException
*/
protected function validateLogin(Request $request)
{
$messages = [
'identity.required' => 'Email or username cannot be empty',
'email.exists' => 'Email or username already registered',
'username.exists' => 'Username is already registered',
'password.required' => 'Password cannot be empty',
];
$request->validate([
'identity' => 'required|string',
'password' => 'required|string',
'email' => 'string|exists:users',
'username' => 'string|exists:users',
], $messages);
}
默认验证仅检查电子邮件,现在我们将其更改为检查电子邮件和用户名。
现在,您有了一个可行的解决方案,可以让您的用户使用电子邮件地址或用户名登录。
如果您有任何疑问,请告诉我:)
via https://dev.to/pramanadiputra/laravel-how-to-let-user-login-with-email-or-username-j2h
最后更新于 2020年8月29日