简体   繁体   English

Laravel - 使用用户名、电子邮件或电话登录

[英]Laravel - Login with username, email or phone

I have implemented login with username or email in my existing project and works fine.我已经在我现有的项目中使用用户名或电子邮件实现了登录并且工作正常。 I want to extend it to login with username, email or phone.我想将其扩展为使用用户名、电子邮件或电话登录。 I want a user to login with either username, email or phone number and password.我希望用户使用用户名、电子邮件或电话号码和密码登录。

Here is my code App\\Http\\Controllers\\Auth\\LoginController这是我的代码 App\\Http\\Controllers\\Auth\\LoginController

<?php

namespace App\Http\Controllers\Auth;
use Socialite;

use Illuminate\Http\Request;
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');
    }

    /**
     * Redirect the user to the GitHub authentication page.
     *
     * @return \Illuminate\Http\Response
     */
      public function redirectToProvider($social)
      {
          return Socialite::driver($social)->redirect();
      }

      /**
       * Obtain the user information from GitHub.
       *
       * @return \Illuminate\Http\Response
       */
      public function handleProviderCallback($social)
      {
          $user = Socialite::driver($social)->user();

          // $user->token;
      }
      /**
       * Get the needed authorization credentials from the request.
       *
       * @param  \Illuminate\Http\Request  $request
       * @return array
       */
        protected function credentials(Request $request)
        {
            $field = filter_var($request->get($this->username()), FILTER_VALIDATE_EMAIL)
                ? $this->username()
                : 'username';

            return [
                $field => $request->get($this->username()),
                'password' => $request->password,
            ];
        }
}

App\\Http\\Controllers\\Auth\\RegisterController App\\Http\\Controllers\\Auth\\RegisterController

<?php

namespace App\Http\Controllers\Auth;

use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|string|max:255',
            'username' => 'required|string|max:20|unique:users',
            'phone' => 'required|string|max:20|unique:users',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
            'gender' => 'required|bool',
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\User
     */
    protected function create(array $data)
    {
        if($data['gender'])
          {
            $avatar = 'default/avatars/male.png';
          }
        else
          {
            $avatar = 'default/avatars/female.png';
          }
        return User::create([
            'name' => $data['name'],
            'gender' => $data['gender'],
            'username' => $data['username'],
            'phone' => $data['phone'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
            'slug' => str_slug($data['username']),
            'avatar' => $avatar,
        ]);
    }
}

Registration works fine and im able to store the user phone to the users table.注册工作正常,我能够将用户电话存储到用户表中。 I have changed the input type for email to text on views/auth/login.php and im able to login with either username or email.我已将电子邮件的输入类型更改为 views/auth/login.php 上的文本,并且我可以使用用户名或电子邮件登录。

When i change the username to phone in LoginController im unable to login with phone as it says Method [phone] does not exist on [App\\Http\\Controllers\\Auth\\LoginController].当我在 LoginController 中将用户名更改为电话时,我无法使用电话登录,因为它说 [App\\Http\\Controllers\\Auth\\LoginController] 上不存在方法 [电话]。

When i add a method当我添加一个方法时

/**
     * Create a new controller instance.
     *
     * @return void
     */
public function phone()
    {
      return 'phone';
    }
/**
       * Get the needed authorization credentials from the request.
       *
       * @param  \Illuminate\Http\Request  $request
       * @return array
       */
        protected function credentials(Request $request)
        {
            $field = filter_var($request->get($this->phone()), FILTER_VALIDATE_EMAIL)
                ? $this->phone()
                : 'phone';

            return [
                $field => $request->get($this->phone()),
                'password' => $request->password,
            ];
        }

It doesn't let me login with phone.它不允许我用手机登录。 Error These credentials do not match our records.错误 这些凭据与我们的记录不匹配。 Also Tried也试过

/**
       * Get the needed authorization credentials from the request.
       *
       * @param  \Illuminate\Http\Request  $request
       * @return array
       */
        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'); 
        }

I'm able to login with phone or email now but not with username How to achieve login with username, email or phone我现在可以使用电话或电子邮件登录,但不能使用用户名 如何使用用户名、电子邮件或电话登录

This code works.此代码有效。 Hope it helps someone.希望它可以帮助某人。

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

If is numeric, login with number.如果是数字,用数字登录。 If is email, login with email address.如果是电子邮件,请使用电子邮件地址登录。 Else try username否则尝试用户名

Final LoginController looks like this最终的 LoginController 看起来像这样

<?php

namespace App\Http\Controllers\Auth;
use Socialite;

use Illuminate\Http\Request;
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');
    }

    /**
     * Redirect the user to the GitHub authentication page.
     *
     * @return \Illuminate\Http\Response
     */
      public function redirectToProvider($social)
      {
          return Socialite::driver($social)->redirect();
      }

      /**
       * Obtain the user information from GitHub.
       *
       * @return \Illuminate\Http\Response
       */
      public function handleProviderCallback($social)
      {
          $user = Socialite::driver($social)->user();

          // $user->token;
      }

      /**
       * Get the needed authorization credentials from the request.
       *
       * @param  \Illuminate\Http\Request  $request
       * @return array
       */
        protected function credentials(Request $request)
        {
          if(is_numeric($request->get('email'))){
            return ['phone'=>$request->get('email'),'password'=>$request->get('password')];
          }
          elseif (filter_var($request->get('email'), FILTER_VALIDATE_EMAIL)) {
            return ['email' => $request->get('email'), 'password'=>$request->get('password')];
          }
          return ['username' => $request->get('email'), 'password'=>$request->get('password')];
        }
}

This code works for Laravel 7此代码适用于 Laravel 7

Step 1 -- Add method username in class LoginController步骤 1 -- 在类 LoginController 中添加方法 username

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

    if(is_numeric($login)){
        $field = 'phone';
    } elseif (filter_var($login, FILTER_VALIDATE_EMAIL)) {
        $field = 'email';
    } else {
        $field = 'username';
    }

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

    return $field;
}

Step 2 -- Add method sendFailedLoginResponse in class LoginController步骤 2 -- 在类 LoginController 中添加方法 sendFailedLoginResponse

protected function sendFailedLoginResponse(Request $request)
{
    throw ValidationException::withMessages([
        'username' => [trans('auth.failed')],
    ]);
}

Final LoginController looks like this最终的 LoginController 看起来像这样

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;

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 = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    /**
     * 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([
            'username' => [trans('auth.failed')],
        ]);
    }

    /**
     * Get the login username to be used by the controller.
     *
     * @return string
     */
    public function username()
    {
        $login = request()->input('username');

        if(is_numeric($login)){
            $field = 'phone';
        } elseif (filter_var($login, FILTER_VALIDATE_EMAIL)) {
            $field = 'email';
        } else {
            $field = 'username';
        }

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

        return $field;
    }
}

Step 3 -- Edit view login.blade.php -> login form步骤 3 -- 编辑视图 login.blade.php -> 登录表单

  • the name from name="email" to name="username"从 name="email" 到 name="username" 的名称
  • change error message from email to username将错误消息从电子邮件更改为用户名
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Login') }}</div>

                <div class="card-body">
                    <form method="POST" action="{{ route('login') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="username" class="col-md-4 col-form-label text-md-right">{{ __('Username/Email/Phone') }}</label>

                            <div class="col-md-6">
                                <input id="username" type="text" class="form-control @error('username') is-invalid @enderror" name="username" value="{{ old('username') }}" required autofocus>

                                @error('username')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

To Login with email or mobile or username , Try this way ...要使用emailmobileusername ,请尝试这种方式...

if(Auth::attempt(['phone' => request('phone'), 'password' => request('password')]) ||
Auth::attempt(['email' => request('email'), 'password' => request('password')]) ||
Auth::attempt(['name' => request('name'), 'password' => request('password')])){
    // do something ...
}

You can add custom check fields also like "Active"='1' as: Auth::attempt(['name' => request('name'), 'password' => request('password'), 'Active' => '1'])您也可以添加自定义检查字段,如 "Active"='1' 为: Auth::attempt(['name' => request('name'), 'password' => request('password'), 'Active' => '1'])

File Address: vendor/laravel/ui/auth-backend/AuthenticatesUsers.php文件地址:vendor/laravel/ui/auth-backend/AuthenticatesUsers.php

protected function credentials(Request $request)
    {

        if (is_numeric($request->get('email'))) {
            return ['mobile' => $request->get('email'), 'password' => $request->get('password')];
        } elseif (filter_var($request->get('email'), FILTER_VALIDATE_EMAIL)) {
            return ['email' => $request->get('email'), 'password' => $request->get('password')];
        }

        return $request->only($request->get('email'), 'password');
    }

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

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