簡體   English   中英

允許在 Laravel 5.4 中使用用戶名或電子郵件登錄

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

現在我已經按照 Laravel 文檔了解如何在身份驗證期間允許用戶名,但它取消了使用電子郵件的能力。 我想允許用戶使用他們的用戶名或電子郵件登錄。 我該怎么做?

我已經按照 Laravel 的文檔將此代碼添加到 LoginController 中,它只允許用戶名登錄。 我希望它接受用戶名或電子郵件進行登錄。

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

我認為更簡單的方法是覆蓋 LoginController 中的 username 方法:

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

按照此鏈接的說明進行操作: https : //laravel.com/docs/5.4/authentication#authenticating-users

然后你可以像這樣檢查用戶輸入

$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'
]);

這只是一個示例。 您可以采取無數種方法來完成相同的任務。

打開您的LoginController.php文件。

  1. 添加此參考

    use Illuminate\\Http\\Request;
  2. 並覆蓋憑據方法

    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, ]; }

Laravel 5.7.11 中測試成功

我認為它更簡單,只需覆蓋AuthenticatesUsers特征中的方法,您的 LoginController 中的憑據方法。 在這里,我已經實現了使用電子郵件或電話登錄。 您可以更改它以滿足您的需要。

登錄控制器.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');
}

您需要從 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
    ]);
}

您的 LoginController 類應該使用 Trait \\Illuminate\\Foundation\\Auth\\AuthenticatesUsers來覆蓋attemptLogin方法,即

class LoginController extends Controller {

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

這是我這樣做的方式:

// 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
    }
 }       

我相信有一種更短的方法可以做到這一點,但對我來說這是有效的並且很容易理解。

將此代碼添加到您的登錄控制器 - 希望它會起作用。 在一個字段中使用電子郵件或用戶名參考登錄

 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

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';

謝謝,這是我感謝您的解決方案。

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