Laravel

Login With Username or Email in Laravel

Login With Username or Email in Laravel
Written by ProgrammingPot

In this tutorial, I’m going to discuss the Login With Username or Email in Laravel v5.5 just released at the end of August 2017.

Quick tip for you guys. What if in your project users can login not only with email but also with some other field, like “username” or “user_id” or whatever? By default Laravel allows only one field like ’email’. That’s actually easy to change.

Let’s start the tutorial 🙂

Login With Username or Email in Laravel


Before starting to look at the code you should be ready with running v5.5 or fresh installation setup on your machine.

If you need a guide for the installation process see the release note and follow the official guide.

Let’s begin with creating authentication scaffolding, migrations for User model.

Generate authentication scaffolding with an artisan command.

php artisan make:auth

As we are going to add username field to the database.

<?php 
use Illuminate\Database\Migrations\Migration; 
use Illuminate\Database\Schema\Blueprint; 
use Illuminate\Support\Facades\Schema; 

class CreateUsersTable extends Migration { 
/** 
* Run the migrations. 
* 
* @return void 
*/ 
public function up() { 
Schema::create('users', function (Blueprint $table) { 
            $table->increments('id');
            $table->string('name');
            $table->string('username')->nullable()->unique();
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Now simply run migration and go ahead.

php artisan migrate

After running this command your database table is now ready with username field support.

Now, open up your User model, add the username field to the $fillable array.

protected $fillable = [
'name', 'email', 'password', 'username',
];

Open up your RegisterController.php, I have added a validation rule for the username in validator() method. Similarly, I have added username field to create() method as well.

<?php

namespace App\Http\Controllers\Auth;

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

class RegisterController extends Controller
{

    use RegistersUsers;

protected $redirectTo = '/home';

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

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|string|max:255',
            'username' => 'required|string|max:20|unique:users',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);
    }

    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'username' => $data['username'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
    }
}

Also, I have changed a little bit on resources/views/auth/register.blade.php to support username, email. So, simply add username field on it.

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Register</div>
                <div class="panel-body">
                    <form class="form-horizontal" method="POST" action="{{ route('register') }}">
                        {{ csrf_field() }}
                        <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
                            <label for="name" class="col-md-4 control-label">Name</label>
                            <div class="col-md-6">
                                <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus>
                                @if ($errors->has('name'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('name') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>
                        <div class="form-group{{ $errors->has('username') ? ' has-error' : '' }}">
                            <label for="username" class="col-md-4 control-label">Username</label>
                            <div class="col-md-6">
                                <input id="username" type="text" class="form-control" name="username" value="{{ old('username') }}" required>
                                @if ($errors->has('username'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('username') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                            <label for="email" class="col-md-4 control-label">E-Mail Address</label>
                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required>
                                @if ($errors->has('email'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('email') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>
                        <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
                            <label for="password" class="col-md-4 control-label">Password</label>
                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control" name="password" required>
                                @if ($errors->has('password'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('password') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>
                            <div class="col-md-6">
                                <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Register
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

You’re done with the registration process. Now let’s look at the login process.

Open up Illuminate\Foundation\Auth\AuthenticatesUsers it has several methods to handle authentication process. In our customization, we only need to override one method credentials() to our App\Http\Controllers\Auth\LoginController.php

Also, don’t forget to add an import use Illuminate\Http\Request; 

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo = '/home';

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

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

You will require changing the login form to support username, email field, simply open up resources/views/auth/login.blade.php and just change the input type to be text from email, just leave other as it is.

 

<input id="email" type="text" class="form-control" name="email" value="{{ old('email') }}" required autofocus>

 

Alright! now we have a full functionality to support login, register with a username, email with Laravel v5.5.

Thanks for reading up to the end. If you have any feedback please leave your comments below. Feel free to share with friends if you like it.

Simple, isn’t it?

Also Read: Laravel Simple CRUD Operation

Happy Coding!

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.