Laravel - 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
<?phpnamespace 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
Step 1 -- Add method username in class LoginController
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
protected function sendFailedLoginResponse(Request $request){ throw ValidationException::withMessages([ 'username' => [trans('auth.failed')], ]);}
Final LoginController looks like this
<?phpnamespace 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
- the name from name="email" to 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 ...
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'])