Laravel User Authentication by Username and Email in Single Login form


Laravel Authentication by username and Email from single Login form.


Recently I received a request from one of my follower on techalyst.com, he was interested to know How to authenticate User In Laravel By Username or Email in combination from one single Login form, something similar to Techalyst Login Form, as we know by default Laravel Authentication is limited to either single choice of whether you want to authenticate by Username or by email, but not combination of both in single form, 

So in this post, i will show you how to override the default behavior of laravel, so that It will accept email or username from single Login form field and do the authentication against the database username column or email column depending on the user input.

Assumption: you have created a Laravel Project Already, and you have added a username column in you users table similar to bellow schema declaration.
Schema::create('users', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->string('username')->unique();
    $table->string('email')->unique();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

Login View

Let's make some changes to the default Laravel Login View, i will modify the Login form, and replace the email field with a common text field and name it as login_name instead of email which is more meaningful, so that user can enter Username or Email in the login_name field.

Open the login.blade.php file from resources/views/auth directory in your favorite editor and replace the email field with the login_name field similar to below.


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

    <div class="col-md-6">
        <input id="login" type="text"
               class="form-control{{ $errors->has('username') || $errors->has('email') ? ' is-invalid' : '' }}"
               name="login_name" value="{{ old('username') ?: old('email') }}" required autofocus>

        @if ($errors->has('username') || $errors->has('email'))
            <span class="invalid-feedback">
                <strong>{{ $errors->first('username') ?: $errors->first('email') }}</strong>
            </span>
        @endif
    </div>
</div>

you may have slight confusion by the line @if ($errors->has('username') || $errors->has('email')) for error checking, let me clear you confusion, since I already renamed the email form field to login_name, in the LoginController I will receive the value from login_name  input and conditionally assess the field type, whether input entered is an email or username value and merged it to global request array with the key as username or email and the value obtained. so that we can expect the $errors array contain either username or email as form field name reference.

LoginController

Let's write the logic for backend controller, so that our form will be fully functional as our expectation.

Open the LoginController.php file located in the app/Http/Controllers/Auth directory in your favorite editor.

and then define a username property in the login controller class.

protected $username;

next define the following method in  your controller class. The method will receive the value of login_name field and asses the field type, merge it back to global request array and return the field type.

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

next call the getLoginMode() from LoginController constructor and assign the value to protected $username; property declared above.

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


If you Laravel version is above Laravel 5.2, then you must define the following method in your LoginController , 

public function username()
{
    return $this->username;
}


and that is all, now your user can enter username or email along with password for authentication,  here is the complete source code for my LoginController.

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

    /**
     * Login username to be used by the controller.
     *
     * @var string
     */
    protected $username;

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

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

    /**
     * Get the login username to be used by the controller.
     *
     * @return string
     */
    public function getLoginMode()
    {
        $login = request()->input('login_name');
        $fieldType = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
        request()->merge([$fieldType => $login]);
        return $fieldType;
    }

    /**
     * Get username property.
     *
     * @return string
     */
    public function username()
    {
        return $this->username;
    }
}


if you have any questions regarding "Laravel User Authentication by Username and Email in Single Login form", please feel free to leave your comment bellow.


Written by Akram Wahid 5 years ago

are you looking for a chief cook who can well craft laravel and vuejs, to make some awsome butterscotch,
yes then it is right time for you to look at my profile.

Do you want to write Response or Comment?

You must be a member of techalyst to proceed!

Continue with your Email ? Sign up / log in

Responses

Be the first one to write a response :(

{{ item.member.name }} - {{ item.created_at_human_readable }}

{{ reply.member.name }} - {{ reply.created_at_human_readable }}