Laravel Middleware: Step by Step Complete Guide

5
3782
How To Use Middleware in Laravel 5 Tutorial

One of the primary requirements of any web application is HTTP request filtering, and we all need to implement that functionality very well. Laravel PHP Framework provides that functionality also, and this concept is called “Laravel Middleware.” 

If you want to know the fundamental CRUD Functionality in Laravel, then check out my article Laravel Crud Example From Scratch

Laravel Middleware

Laravel middleware, as its name suggests implements some functionality during the request hit on the particular URI. It is like layers; we need to put in between our request and response. It provides us very flexible API to do that.

To implement custom middleware in Laravel within no time, fire one command, and all setup. Next, we need to write logic to the particular function and define that in our application. That is it, Folks. Okay, so let’s deep dive into it with some examples.

Step 1: Create a Laravel project

 Type the following command in your CMD.

composer create-project laravel/laravel LaravelMiddleware --prefer-dist

Go to phpMyAdmin and create one database called laravel middleware. You can name it anything.

Switch to your editor, edit the .env file and put your database credentials in it.

Step: 2 Laravel Admin Middleware

Now, To check if the current user is an administrator or not. So go to your users’ table migration file and add one more field called isAdmin, and its data type is boolean.

<?php

// create_users_migrations

  public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email');
            $table->string('password');
            $table->boolean('isAdmin')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

Now run the following command.

php artisan migrate

The next step is to create the Authentication functionality provided by Laravel. So type the following in your terminal.

Laravel Authentication

php artisan make:auth

So the auth scaffold will generate successfully.

Start the server by typing the following command.

php artisan serve

Now create three users. So go to the following URL: http://localhost:8000/register.

We have not assigned any users to admin, but we can do it manually. But, remember, in the real-time web application, you need to provide some interface to give administrative rights.

Here I am just showcasing how you can deal with admin middleware after signing in the form.

So, for now, assign any user’s isAdmin field to value one manually in the database.

Step 3: Make one basic Laravel Middleware.

Create one middleware by typing the following Laravel Command.

php artisan make:middleware Admin

Navigate to the following directory.  app  >>  Http  >>  Middleware  >>  Admin.php

You can see there is some boilerplate provided by Laravel.  

There is mainly one function you have to deal with, and that is handle()

// Middleware Admin.php

  /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }

We need to write the logic in this function to filter the request, and if it satisfies, go to the destination page; otherwise, go back to login or whatever redirect page you will provide.

I am writing one logic in this function.

  /**  Admin.php
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
      if(auth()->user()->isAdmin == 1){
        return $next($request);
      }
        return redirect('home')->with('error','You have not admin access');
    }

Now, I need to register this route in the app  >>  Http  >>  Kernel.php

You can register this route in two separate ways.

  1. You can register as a global middleware.
  2. You can register as a particular route called route middleware.

We are registering as a route middleware so, go to the protected $routeMiddleware property.

<?php

// Kernel.php

protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'admin' => \App\Http\Middleware\Admin::class,
    ];

Here as you can see, I have added our custom middleware called admin.

Now, if we want to assign any route to this middleware admin, these routes are protected and only accessible when an authorized user is admin; otherwise, it will redirect to the homepage.

Step 4: Admin-protected route middleware.

Create one route, which needs to be admin protected, and if the user is not an admin, it will redirect to the home page; otherwise, he can access this page.

<?php

// web.php

Route::get('admin/routes', 'HomeController@admin')->middleware('admin');

We need to put this link on the home page after the user has signed in.

<!-- home.blade.php -->

@extends('layouts.app')

@section('content')
<div class="container">
  @if(\Session::has('error'))
    <div class="alert alert-danger">
      {{\Session::get('error')}}
    </div>
  @endif
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Dashboard</div>

                <div class="panel-body">
                    <a href="{{url('admin/routes')}}">Admin</a>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

All we need is to code the admin function that resides in HomeController.

<?php

// HomeController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HomeController extends Controller
{
    
    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('home');
    }

    public function admin()
    {
        return view('admin');
    }

}

Step 5: Make one blade file.

Create one view called admin.blade.php in the root of the views folder.

<!-- admin.blade.php -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>ADMIN PAGE</title>
  </head>
  <body>
    WELCOME TO ADMIN ROUTE
  </body>
</html>

Now, go to the login page  and log in with the isAdmin field 1

Here is my login page for Laravel.

Laravel 5 middleware tutorial

After logging in, this is how my screen looks like this.

Laravel 5.4 Middleware

You are logged in as an admin, so; you can see the following page.

If you are logged in as a regular user, you will redirect to the same page as in our case; it’s a home page with the following error.

Laravel Route Middleware

Laravel Group Middleware

<?php

// web.php

Route::group(['middleware' => ['admin']], function () {
    Route::get('admin/routes', 'HomeController@admin');
});

We can use middleware groups to assign one middleware to multiple routes. It is effortless.

If I do not want to show the Admin links to the normal user, I have put a condition like if authenticate the user is an admin then, and then we can show him that route otherwise not. But in this example, I have not put anything like that.

I want to show you that if you are not an admin and still try to access this route, you will redirect with a proper message.

Multiple Middlewares in Single Route

We can put two middlewares into one route at a time.

Route::get('admin/routes', 'HomeController@admin')->middleware(['admin','auth']);

Auth Middleware Provided By Laravel

<?php

// Kernel.php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array
     */
    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    ];
}

The auth and guest middlewares are related to the Authentication of the User.

VerifyCSRFToken is another global middleware and protects us from Cross-Site Request Forgery attacks in every POST request.

This middleware throws TokenMismatchException if the POST request does not contain CSRF Token.

That is it for Laravel Middleware Example.

Github Code

Steps to use Github code

  1. Clone the repo in your local.
  2. Go to the project’s root and run the command “composer update. “
  3. Then, edit the .env file and use your MySQL database credentials.
  4. Add one admin field in the user’s table.
  5. Run the command, “php artisan migrate. “
  6. We need to bootstrap the Laravel server, so run “php artisan serve. “
  7. If now go to this URL:http://localhost:8000/registerandcreate three new users and change one of the user’s admin values to one
  8. Now log in like three different users and click the admin link on the home page; if you apply the middleware in that link’s route, it will work as described above.

Recommended Posts

Laravel JWT Authentication

Laravel Stripe

Laravel Braintree

Laravel Cronjob Scheduling

Laravel Gates

5 Comments

Leave A Reply

Please enter your comment!
Please enter your name here

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