Laravel 9 Auth Login and Registration with Username or Email
Tags: laravel, php, javascript
Published: 2022-03-24 08:28:40

Originally posted @ https://codeanddeploy.com visit and download the sample code: https://codeanddeploy.com/blog/laravel/laravel-8-authentication-login-and-registration-with-username-or-email

[![Advanced Laravel SAAS Starter Kit with CRUD Generator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyjyev8tz3r8vi2w3on1.png)](https://1.envato.market/5g5QAn)

[Advanced Laravel SAAS Starter Kit with CRUD Generator - GET YOUR COPY NOW!](https://1.envato.market/5g5QAn)


In this post, I will share how to implement **Laravel 8, 9 custom auth login and registration** with username or email. We know that Laravel Framework is one of the best PHP Frameworks because of these advanced features and development tools that help make your development fast; that's why many PHP Developers use it and recommend it. Laravel additionally helps web developers to simplify their development process with clean and reusable code.

 

As I said above that I will share how to create a simple and clean authentication for your Laravel app with username or email. We know that authentication is one of the most important to implement before coding your application to control your users to access sensitive data.

![laravel-8-authentication-login-and-registration-with-username-or-email](https://ecn-storage.s3.us-west-2.amazonaws.com/articles/laravel-8-authentication-login-and-registration-with-username-or-email-HqvAj2a4D7x980.webp?ctm=1629626640)

I will give you easy steps for you to understand clearly.

 

## Step 1: Create Laravel App

I assume that you have already set up your composer on your system. Run the following coding to install the new Laravel app. However, you can skip this step if you have the Laravel app installed already.

```php
composer create-project --prefer-dist laravel/laravel login-and-registration
```
Next, navigate the **login-and-registration** folder with the following command.

```php
cd login-and-registration
```

## Step 2: Setup Database Credentials

Next, create your database you can use the command to create a database or in PHPMyAdmin. Then once created navigate the **.env** file and update your database credentials.

```php
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_db_name
DB_USERNAME=your_db_username
DB_PASSWORD=your_db_password
 
```

The Laravel default comes with a User model and migration files. But before running the migrate command we need to update your user table migration which can be found here > {project_folder}\database\migrations\2014_10_12_000000_create_users_table.php and add the username field then update the **name** field to nullable so that in registration we require the email, username, and password. See the updated migration code below.

```php
Schema::create('users', function (Blueprint $table) {
   $table->id();
   $table->string('name')->nullable();
   $table->string('email')->unique();
   $table->string('username')->unique();
   $table->timestamp('email_verified_at')->nullable();
   $table->string('password');
   $table->rememberToken();
   $table->timestamps();
});
```

Once updated our migrations are now ready to migrate just run to your terminal the following command:

```php
php artisan migrate
```

## Step 3: Setup Model

Next, we need to modify our **App\Models\User.php** model and add the username as fillable. See the updated code in the following:

```php
/**
 * The attributes that are mass assignable.
 *
 * @var array
*/
protected $fillable = [
  'name',
  'email',
  'username',
  'password',
];
```

Then next, we will add this method **setPasswordAttribute** so that for every user registered, the **password** will always be **encrypted**. This is called Laravel mutators to know more about it just visit their documentation [here](https://laravel.com/docs/8.x/eloquent-mutators).


```php
/**
 * Always encrypt the password when it is updated.
 *
  * @param $value
 * @return string
 */
public function setPasswordAttribute($value)
{
   $this->attributes['password'] = bcrypt($value);
}
```

Don't worry to see the complete code of this `User.php` model just download the full source code of this tutorial below.

## Step 4: Setup Registration Controller

To set up the registration controller just use your terminal and run the following command.

```php
php artisan make:controller RegisterController
```

Now, you already generated our RegistrerController which you can found it here > **App\Http\Controllers\RegisterController.php** now open it and see the following code below:

```php
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Requests\RegisterRequest;

class RegisterController extends Controller
{
    /**
     * Display register page.
     * 
     * @return \Illuminate\Http\Response
     */
    public function show()
    {
        return view('auth.register');
    }

    /**
     * Handle account registration request
     * 
     * @param RegisterRequest $request
     * 
     * @return \Illuminate\Http\Response
     */
    public function register(RegisterRequest $request) 
    {
        $user = User::create($request->validated());

        auth()->login($user);

        return redirect('/')->with('success', "Account successfully registered.");
    }
}
```

## Step 5: Setup Registration Request

We need to separate our request validation for our registration process. So that our code is clean in our controller and not bloated. So we will create our **RegisterRequest** just follow the following command below:

```php
php artisan make:request RegisterRequest
```

Now you have already created the RegisterRequest which you can find it here > **App\Http\Requests\RegisterRequest.php** then next we will add our validation rules. Just see the following code below:


```php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class RegisterRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => 'required|email:rfc,dns|unique:users,email',
            'username' => 'required|unique:users,username',
            'password' => 'required|min:8',
            'password_confirmation' => 'required|same:password'
        ];
    }
}
```

Now you have a registration validation already.

 

## Step 6: Setup Login Controller

To set up the login controller just use your terminal and run the following command.

```php
php artisan make:controller LoginController
```

Now, you already generated our LoginController which you can found it here > **App\Http\Controllers\LoginController.php** now open it and see the following code below:

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    /**
     * Display login page.
     * 
     * @return Renderable
     */
    public function show()
    {
        return view('auth.login');
    }

    /**
     * Handle account login request
     * 
     * @param LoginRequest $request
     * 
     * @return \Illuminate\Http\Response
     */
    public function login(LoginRequest $request)
    {
        $credentials = $request->getCredentials();

        if(!Auth::validate($credentials)):
            return redirect()->to('login')
                ->withErrors(trans('auth.failed'));
        endif;

        $user = Auth::getProvider()->retrieveByCredentials($credentials);

        Auth::login($user);

        return $this->authenticated($request, $user);
    }

    /**
     * Handle response after user authenticated
     * 
     * @param Request $request
     * @param Auth $user
     * 
     * @return \Illuminate\Http\Response
     */
    protected function authenticated(Request $request, $user) 
    {
        return redirect()->intended();
    }
}
```

## Step 7: Setup Login Request

Next, we will create our `LoginRequest` just follow the following command below:

```php
php artisan make:request LoginRequest
```

Now you have already created the LoginRequest which you can find it here > **App\Http\Requests\LoginRequest.php** then next we will add our validation rules. Just see the following code below:

```php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;

class LoginRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'username' => 'required',
            'password' => 'required'
        ];
    }

    /**
     * Get the needed authorization credentials from the request.
     *
     * @return array
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function getCredentials()
    {
        // The form field for providing username or password
        // have name of "username", however, in order to support
        // logging users in with both (username and email)
        // we have to check if user has entered one or another
        $username = $this->get('username');

        if ($this->isEmail($username)) {
            return [
                'email' => $username,
                'password' => $this->get('password')
            ];
        }

        return $this->only('username', 'password');
    }

    /**
     * Validate if provided parameter is valid email.
     *
     * @param $param
     * @return bool
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    private function isEmail($param)
    {
        $factory = $this->container->make(ValidationFactory::class);

        return ! $factory->make(
            ['username' => $param],
            ['username' => 'email']
        )->fails();
    }
}
```

As you can see above our `LoginRequest.php` we have our additional method called **getCredentials()** this function will support the username/email login as you can see we have username checking above if email or not.

 

## Step 8: Setup Logout Controller


To set up the logout controller just use your terminal and run the following command.

```php
php artisan make:controller LogoutController
```
Now, you already generated our LogoutController which you can found it here > **App\Http\Controllers\LogoutController.php** now open it and see the following code below:

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;

class LogoutController extends Controller
{
    /**
     * Log out account user.
     *
     * @return \Illuminate\Routing\Redirector
     */
    public function perform()
    {
        Session::flush();
        
        Auth::logout();

        return redirect('login');
    }
}
```

## Step 9: Setup Home Controller

To set up the logout controller just use your terminal and run the following command.

```php
php artisan make:controller HomeController
```
Now, you already generated our `HomeController` which you can found it here > **App\Http\Controllers\HomeController.php** now open it and see the following code below:


```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HomeController extends Controller
{
    public function index() 
    {
        return view('home.index');
    }
}
```

## Step 10: Setup Routes

Next, we will set up our routes which we can find here **routes/web.php** since we have already set up our **controllers** and **validators**.

```php
<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::group(['namespace' => 'App\Http\Controllers'], function()
{   
    /**
     * Home Routes
     */
    Route::get('/', 'HomeController@index')->name('home.index');

    Route::group(['middleware' => ['guest']], function() {
        /**
         * Register Routes
         */
        Route::get('/register', 'RegisterController@show')->name('register.show');
        Route::post('/register', 'RegisterController@register')->name('register.perform');

        /**
         * Login Routes
         */
        Route::get('/login', 'LoginController@show')->name('login.show');
        Route::post('/login', 'LoginController@login')->name('login.perform');

    });

    Route::group(['middleware' => ['auth']], function() {
        /**
         * Logout Routes
         */
        Route::get('/logout', 'LogoutController@perform')->name('logout.perform');
    });
});
```

As you can see above in this line **"Route::group(['middleware' => ['auth']], function() {"** we protected the logout route that can be access only if user authenticated. If you have other routes that need to protect just add on this route group.

 

## Step 11: Setup Our View


Next, we will set up our views using Bootstrap with a simple theme layout. To know more about bootstrap documentation just visit [here](https://getbootstrap.com/docs/5.1/getting-started/introduction/).

 

You need to create a **layouts** folder inside **resources/views** then create a file **resources/views/layouts/auth-master.blade.php** see the following code below:

```php
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
    <meta name="generator" content="Hugo 0.87.0">
    <title>Signin Template · Bootstrap v5.1</title>

    <!-- Bootstrap core CSS -->
    <link href="{!! url('assets/bootstrap/css/bootstrap.min.css') !!}" rel="stylesheet">
    <link href="{!! url('assets/css/signin.css') !!}" rel="stylesheet">
    
    <style>
      .bd-placeholder-img {
        font-size: 1.125rem;
        text-anchor: middle;
        -webkit-user-select: none;
        -moz-user-select: none;
        user-select: none;
      }

      @media (min-width: 768px) {
        .bd-placeholder-img-lg {
          font-size: 3.5rem;
        }
      }
    </style>

    
    <!-- Custom styles for this template -->
    <link href="signin.css" rel="stylesheet">
</head>
<body class="text-center">
    
    <main class="form-signin">

        @yield('content')
        
    </main>
    

</body>
</html>
```

Next, create a file **resources/views/layouts/app-master.blade.php** see the following code below:

```php
<!doctype html>
<html lang="en">
    <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
    <meta name="generator" content="Hugo 0.87.0">
    <title>Fixed top navbar example · Bootstrap v5.1</title>

    <!-- Bootstrap core CSS -->
    <link href="{!! url('assets/bootstrap/css/bootstrap.min.css') !!}" rel="stylesheet">

    <style>
      .bd-placeholder-img {
        font-size: 1.125rem;
        text-anchor: middle;
        -webkit-user-select: none;
        -moz-user-select: none;
        user-select: none;
      }

      @media (min-width: 768px) {
        .bd-placeholder-img-lg {
          font-size: 3.5rem;
        }
      }
    </style>

    
    <!-- Custom styles for this template -->
    <link href="{!! url('assets/css/app.css') !!}" rel="stylesheet">
</head>
<body>
    
    @include('layouts.partials.navbar')

    <main class="container">
        @yield('content')
    </main>

    <script src="{!! url('assets/bootstrap/js/bootstrap.bundle.min.js') !!}"></script>
      
  </body>
</html>
```

Next, create a new folder inside **resources/views/layouts** called **partials** folder then create a file **resources/views/layouts/partials/navbar.blade.php** see the following code below:

```php
<header class="p-3 bg-dark text-white">
  <div class="container">
    <div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
      <a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none">
        <svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"/></svg>
      </a>

      <ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
        <li><a href="#" class="nav-link px-2 text-secondary">Home</a></li>
        <li><a href="#" class="nav-link px-2 text-white">Features</a></li>
        <li><a href="#" class="nav-link px-2 text-white">Pricing</a></li>
        <li><a href="#" class="nav-link px-2 text-white">FAQs</a></li>
        <li><a href="#" class="nav-link px-2 text-white">About</a></li>
      </ul>

      <form class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3">
        <input type="search" class="form-control form-control-dark" placeholder="Search..." aria-label="Search">
      </form>

      @auth
        {{auth()->user()->name}}
        <div class="text-end">
          <a href="{{ route('logout.perform') }}" class="btn btn-outline-light me-2">Logout</a>
        </div>
      @endauth

      @guest
        <div class="text-end">
          <a href="{{ route('login.perform') }}" class="btn btn-outline-light me-2">Login</a>
          <a href="{{ route('register.perform') }}" class="btn btn-warning">Sign-up</a>
        </div>
      @endguest
    </div>
  </div>
</header>
```

Then next, create a file **resources/views/layouts/partials/messages.blade.php** see the following code below:

```php
@if(isset ($errors) && count($errors) > 0)
    <div class="alert alert-warning" role="alert">
        <ul class="list-unstyled mb-0">
            @foreach($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

@if(Session::get('success', false))
    <?php $data = Session::get('success'); ?>
    @if (is_array($data))
        @foreach ($data as $msg)
            <div class="alert alert-warning" role="alert">
                <i class="fa fa-check"></i>
                {{ $msg }}
            </div>
        @endforeach
    @else
        <div class="alert alert-warning" role="alert">
            <i class="fa fa-check"></i>
            {{ $data }}
        </div>
    @endif
@endif
```
Then next, create our **auth** folder inside **resources/views** then create a file **resources/views/auth/register.blade.php** see the following code below:

```php
@extends('layouts.auth-master')

@section('content')
    <form method="post" action="{{ route('register.perform') }}">

        <input type="hidden" name="_token" value="{{ csrf_token() }}" />
        <img class="mb-4" src="{!! url('images/bootstrap-logo.svg') !!}" alt="" width="72" height="57">
        
        <h1 class="h3 mb-3 fw-normal">Register</h1>

        <div class="form-group form-floating mb-3">
            <input type="email" class="form-control" name="email" value="{{ old('email') }}" placeholder="name@example.com" required="required" autofocus>
            <label for="floatingEmail">Email address</label>
            @if ($errors->has('email'))
                <span class="text-danger text-left">{{ $errors->first('email') }}</span>
            @endif
        </div>

        <div class="form-group form-floating mb-3">
            <input type="text" class="form-control" name="username" value="{{ old('username') }}" placeholder="Username" required="required" autofocus>
            <label for="floatingName">Username</label>
            @if ($errors->has('username'))
                <span class="text-danger text-left">{{ $errors->first('username') }}</span>
            @endif
        </div>
        
        <div class="form-group form-floating mb-3">
            <input type="password" class="form-control" name="password" value="{{ old('password') }}" placeholder="Password" required="required">
            <label for="floatingPassword">Password</label>
            @if ($errors->has('password'))
                <span class="text-danger text-left">{{ $errors->first('password') }}</span>
            @endif
        </div>

        <div class="form-group form-floating mb-3">
            <input type="password" class="form-control" name="password_confirmation" value="{{ old('password_confirmation') }}" placeholder="Confirm Password" required="required">
            <label for="floatingConfirmPassword">Confirm Password</label>
            @if ($errors->has('password_confirmation'))
                <span class="text-danger text-left">{{ $errors->first('password_confirmation') }}</span>
            @endif
        </div>

        <button class="w-100 btn btn-lg btn-primary" type="submit">Register</button>
        
        @include('auth.partials.copy')
    </form>
@endsection
```

Then create a **partials** folder inside **auth** folder. Then create a file **resources/views/auth/partials/copy.blade.php** see the following code below:

```php
<p class="mt-5 mb-3 text-muted">&copy; {{date('Y')}}</p>
```

Then last create a **home** folder inside the **resources/views** folder then create a file **resources/views/home/index.blade.php** see the following code below:

```php
@extends('layouts.app-master')

@section('content')
    <div class="bg-light p-5 rounded">
        @auth
        <h1>Dashboard</h1>
        <p class="lead">Only authenticated users can access this section.</p>
        <a class="btn btn-lg btn-primary" href="https://codeanddeploy.com" role="button">View more tutorials here &raquo;</a>
        @endauth

        @guest
        <h1>Homepage</h1>
        <p class="lead">Your viewing the home page. Please login to view the restricted data.</p>
        @endguest
    </div>
@endsection
```
Now our views are already set up. Next, we need to download bootstrap and save it inside the **public/assets** directory.

 

This is the bootstrap files example in this tutorial:

**public/assets/bootstrap/css/bootstrap.min.css**

**public/assets/bootstrap/js/bootstrap.bundle.min.js**

 

Or download the source code of this tutorial below.

 

Now our Laravel authentication with username or email login is ready but we have another small customization the redirect default after login. Which we can found in App\Providers\RouteServiceProvider.php then change the original code below:

```php
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.

* @var string
*/
public const HOME = '/home';
```

to this code.


```php
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* @var string
*/
public const HOME = '/';
```

But take note it's up to you to change it. I just give you an idea of how to modify it that is suitable to your need. If you need to redirect after login to /dashboard or /admin then it's up to you to change it.

 

## Step 12: Run The Development Server

Finally, we have already done the process of our Laravel authentication. Let's run a command to your terminal to run your server and test if our code is working.

```php
php artisan serve
```

And add the following URL to your web browser.\

```php
http://127.0.0.1:8000/
```

You will see the homepage if not yet authenticated as shown below:

![laravel-8-authentication-login-and-registration-with-username-or-email](https://ecn-storage.s3.us-west-2.amazonaws.com/articles/laravel-8-authentication-login-and-registration-with-username-or-email-mLV6bA8wTGx980.webp?ctm=1629626378)

![laravel-8-authentication-login-and-registration-with-username-or-email](https://ecn-storage.s3.us-west-2.amazonaws.com/articles/laravel-8-authentication-login-and-registration-with-username-or-email-XeG60n4Ke8x980.webp?ctm=1629626472)

As you can see now you already see the Logout menu above.

Now you have a custom Laravel registration and login with username/email that can apply to your app. I hope this simple tutorial may help you.

NOTE: Don't forget to import the classes uses in a specific class or controller when copying my code above.

[![Advanced Laravel SAAS Starter Kit with CRUD Generator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wyjyev8tz3r8vi2w3on1.png)](https://1.envato.market/5g5QAn)

[Advanced Laravel SAAS Starter Kit with CRUD Generator - GET YOUR COPY NOW!](https://1.envato.market/5g5QAn)


I hope this tutorial can help you. Kindly visit here https://codeanddeploy.com/blog/laravel/laravel-8-authentication-login-and-registration-with-username-or-email if you want to download this code.

Happy coding :)