简体   繁体   English

允许在 Laravel 5.4 中使用用户名或电子邮件登录

[英]Allow login using username or email in Laravel 5.4

Now I've followed the Laravel documentation on how to allow usernames during authentication, but it takes away the ability to use the email.现在我已经按照 Laravel 文档了解如何在身份验证期间允许用户名,但它取消了使用电子邮件的能力。 I want to allow users to use their username or email to login.我想允许用户使用他们的用户名或电子邮件登录。 How do I go about this?我该怎么做?

I've added this code to the LoginController as per Laravel's Documentation and it only allows username for login.我已经按照 Laravel 的文档将此代码添加到 LoginController 中,它只允许用户名登录。 I want it to accept username or email for login.我希望它接受用户名或电子邮件进行登录。

public function username () {
    return 'username';
}

I think a simpler way is to just override the username method in LoginController:我认为更简单的方法是覆盖 LoginController 中的 username 方法:

public function username()
{
   $login = request()->input('login');
   $field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
   request()->merge([$field => $login]);
   return $field;
}

Follow instructions from this link: https://laravel.com/docs/5.4/authentication#authenticating-users按照此链接的说明进行操作: https : //laravel.com/docs/5.4/authentication#authenticating-users

Then you can check for the user input like this然后你可以像这样检查用户输入

$username = $request->username; //the input field has name='username' in form

if(filter_var($username, FILTER_VALIDATE_EMAIL)) {
    //user sent their email 
    Auth::attempt(['email' => $username, 'password' => $password]);
} else {
    //they sent their username instead 
    Auth::attempt(['username' => $username, 'password' => $password]);
}

//was any of those correct ?
if ( Auth::check() ) {
    //send them where they are going 
    return redirect()->intended('dashboard');
}

//Nope, something wrong during authentication 
return redirect()->back()->withErrors([
    'credentials' => 'Please, check your credentials'
]);

This is just a sample.这只是一个示例。 THere are countless various approaches you can take to accomplish the same.您可以采取无数种方法来完成相同的任务。

Open your LoginController.php file.打开您的LoginController.php文件。

  1. Add this reference添加此参考

    use Illuminate\\Http\\Request;
  2. And override the credentials method并覆盖凭据方法

    protected function credentials(Request $request) { $field = filter_var($request->get($this->username()), FILTER_VALIDATE_EMAIL) ? 'email' : 'username'; return [ $field => $request->get($this->username()), 'password' => $request->password, ]; }

Successfully tested in Laravel 5.7.11Laravel 5.7.11 中测试成功

I think its even more simple, just override the method from AuthenticatesUsers traits, credentials method in your LoginController.我认为它更简单,只需覆盖AuthenticatesUsers特征中的方法,您的 LoginController 中的凭据方法。 Here I have implemented to login with either email or phone.在这里,我已经实现了使用电子邮件或电话登录。 You can change it to fit your needs.您可以更改它以满足您的需要。

LoginController.php登录控制器.php

protected function credentials(Request $request)
{
    if(is_numeric($request->get('email'))){
        return ['phone'=>$request->get('email'),'password'=>$request->get('password')];
    }
    return $request->only($this->username(), 'password');
}

You need to override protected function attemptLogin(Request $request) method from \\Illuminate\\Foundation\\Auth\\AuthenticatesUsers Trait in your LoginController ie in my LoginController class您需要从 LoginController 中的\\Illuminate\\Foundation\\Auth\\AuthenticatesUsers Trait 覆盖protected function attemptLogin(Request $request)方法,即在我的 LoginController 类中

protected function attemptLogin(Request $request) {

    $identity = $request->get("usernameOrEmail");
    $password = $request->get("password");

    return \Auth::attempt([
        filter_var($identity, FILTER_VALIDATE_EMAIL) ? 'email' : 'username' => $identity,
        'password' => $password
    ]);
}

Your LoginController class should use Trait \\Illuminate\\Foundation\\Auth\\AuthenticatesUsers in order to override attemptLogin method ie您的 LoginController 类应该使用 Trait \\Illuminate\\Foundation\\Auth\\AuthenticatesUsers来覆盖attemptLogin方法,即

class LoginController extends Controller {

     use \Illuminate\Foundation\Auth\AuthenticatesUsers;
     .......
     .......
}

This is the way I do it:这是我这样做的方式:

// get value of input from form (email or username in the same input)
 $email_or_username = $request->input('email_or_username');

 // check if $email_or_username is an email
 if(filter_var($email_or_username, FILTER_VALIDATE_EMAIL)) { // user sent his email 

    // check if user email exists in database
    $user_email = User::where('email', '=', $request->input('email_or_username'))->first();

    if ($user_email) { // email exists in database
       if (Auth::attempt(['email' => $email_or_username, 'password' => $request->input('password')])) {
          // success
       } else {
          // error password
       }
    } else {
       // error: user not found
    }

 } else { // user sent his username 

    // check if username exists in database
    $username = User::where('name', '=', $request->input('email_or_username'))->first();

    if ($username) { // username exists in database
       if (Auth::attempt(['name' => $email_or_username, 'password' => $request->input('password')])) {
          // success
       } else {
          // error password
       }
    } else {
       // error: user not found
    }
 }       

I believe there is a shorter way to do that, but for me this works and is easy to understand.我相信有一种更短的方法可以做到这一点,但对我来说这是有效的并且很容易理解。

Add this code to your login controller - Hope it will works.将此代码添加到您的登录控制器 - 希望它会起作用。 Reference login with email or username in one field 在一个字段中使用电子邮件或用户名参考登录

 public function __construct()
{
    $this->middleware('guest')->except('logout');

    $this->username = $this->findUsername();
}

public function findUsername()
{
    $login = request()->input('login');

    $fieldType = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';

    request()->merge([$fieldType => $login]);

    return $fieldType;
}

public function username()
{
    return $this->username;
}
public function username()
{
    //return ‘identity’;
    $login = request()->input('identity');
    $field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'phone';
    request()->merge([$field => $login]);

    return $field;
}


protected function validateLogin(Request $request)
{
    $messages = [
        'identity.required' => 'Email or username cannot be empty',
        'email.exists' => 'Email or username already registered',
        'phone.exists' => 'Phone No is already registered',
        'password.required' => 'Password cannot be empty',
    ];

    $request->validate([
        'identity' => 'required|string',
        'password' => 'required|string',
        'email' => 'string|exists:users',
        'phone' => 'numeric|exists:users',
    ], $messages);
}

https://dev.to/pramanadiputra/laravel-how-to-let-user-login-with-email-or-username-j2h https://dev.to/pramanadiputra/laravel-how-to-let-user-login-with-email-or-username-j2h

This solution of "Rabah G" works for me in Laravel 5.2. I modified a litle but is the same

$loginType = request()->input('useroremail');
$this->username = filter_var($loginType, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
request()->merge([$this->username => $loginType]);
return property_exists($this, 'username') ? $this->username : 'email';

Thanks, this is the solution I got thanks to yours.谢谢,这是我感谢您的解决方案。

protected function credentials(Request $request) { 

$login = request()->input('email'); 

// Check whether username or email is being used
$field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'user_name'; 
return [ 
   $field    => $request->get('email'), 
  'password' => $request->password, 
  'verified' => 1 
]; 
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM