Middleware and component are two handy tricks in Laravel to break down coding in simple re-useable chucks of code. ‘Middleware’ belongs to back-end side whereas ‘component’ is related to front-end side. As we have UI components like button, message pop-up, modal etc. which can be reused anywhere in layout, middleware represents a chunk of re-useable code which could be attached to the app or a route in order to evaluate an HTTP request and then let it pass accordingly further inside the app.
Let’s pick up from our previous tutorial where we embedded simple user role functionality in Laravel app; and then utilize middleware and view component concepts to see the user roles in action.
(Note: If you’ve been through the previous tutorial, you can skip the steps reproduced below, up to the creation of users. Otherwise, follow along all the steps given hereunder.)
Laravel 9.x requires a minimum PHP version of 8.0. This tutorial assumes that you are using Linux, MacOS or WSL on Windows and Node.js, Composer and PHP 8 along with required modules i.e bcmatch, sqlite, mbstring, xml, zip, gd, mcrypt are properly installed. Also make sure that SQLite is installed as we’ll be using SQLite to keep things simple and quick; you may use MySQL or PostgreSQL as you like, however make sure the corresponding PHP module is installed too.
Using Composer, enter following command in terminal to install Laravel 9;
composer create-project laravel/laravel app 9.*
Now go inside newly created app directory by executing;
cd app
Then, setup database and Laravel environment file. Here, I’m configuring SQLite database for simplicity purposes.
Being in parent directory (app), execute following command in order to create new SQLite database file;
touch database/database.sqlite
Then find .env config file in the parent directory, open it and amend DB_CONNECTION line as follows;
DB_CONNECTION = sqlite
You can remove DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD from .env when using SQLite database.
Now, enter following command to create update migration for users table:
php artisan make:migration update_users_table
Then insert following code inside the newly created file database/migrations/(date_stamp)_update_users_table.php:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('role')->nullable();
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['role']);
});
}
};
Now enter following command to run migrations:
php artisan migrate
Then open app/Models/User.php and insert ‘role‘ field in protected $fillable array as given below;
protected $fillable = [
'name',
'email',
'password',
'role',
];
It’s all set to insert data, so let’s create a couple of users by invoking tinker;
php artisan tinker
Then, create first user by entering following command;
User::create(["name"=> "John Doe", "email"=>"john@gmail.com", "password"=>bcrypt("password"), "role"=>"admin"]);
Create second user by entering following command;
User::create(["name"=> "Jane Doe", "email"=>"jane@gmail.com", "password"=>bcrypt("password"), "role"=>"user"]);
Type ‘exit’ and press Enter to quit tinker.
Now, we’ll create a middleware which could be attached to any route for performing an evaluation over HTTP request. As mentioned earlier, middleware is a convenient way to evaluate certain condition on HTTP request before letting it through further inside the app. In our case, whenever a user accesses a route, the attached middleware will check whether the logged-in user’s role is ‘admin‘ or not, then it’ll let the HTTP request pass through accordingly i.e., if the logged-in user’s role is not ‘admin‘, he/she will be taken back to previous view with an alert message.
Let’s enter following command to create a middleware IsAdmin:
php artisan make:middleware IsAdmin
Insert following code inside the newly created file app/Http/Middleware/IsAdmin.php:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class IsAdmin
{
public function handle(Request $request, Closure $next)
{
if ($request->user()->role !== 'admin') {
return redirect()->back()->with('alert', 'You are not admin!');
}
return $next($request);
}
}
Then, change app/Http/Kernel.php as follows in order to define ‘admin‘ key for IsAdmin class:
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
// ...
'admin' => \App\Http\Middleware\IsAdmin::class,
];
Let’s add the front-end action to see how user role and middleware will act. For that, first import Breeze package which will add user authentication;
composer require laravel/breeze:* --dev
Then install Breeze by entering following command;
php artisan breeze:install
The above command will install the required node.js modules and basic user authentication and then compile UI assets for the first time.
Now open resources/views/dashboard.blade.php and amend it as follows:
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('User Dashboard') }}
</h2>
</x-slot>
<x-auth-session-alert :alert="session('alert')" />
<div class="py-6">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
You're on User Dashboard!
</div>
</div>
</div>
</div>
</x-app-layout>
Then, create another dashboard for admin by entering following command;
touch resources/views/dashboard-admin.blade.php
Insert following code inside resources/views/dashboard-admin.blade.php;
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-red-800 leading-tight">
{{ __('Admin Dashboard') }}
</h2>
</x-slot>
<x-auth-session-alert :alert="session('alert')" />
<div class="py-6">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200 text-red-800">
You're on Admin Dashboard!
</div>
</div>
</div>
</div>
</x-app-layout>
Let’s add a view component to display alert flash message. To create a view component, enter following command:
php artisan make:component auth-session-alert --view
Then open newly created file resources/views/components/auth-session-alert.blade.php and insert following code:
@props(['alert'])
@if ($alert)
<div {{ $attributes->merge(['class' => 'font-medium text-sm text-red-600 p-2 mt-4 mx-2 bg-red-100 sm:rounded-lg']) }}>
{{ $alert }}
</div>
@endif
Execute following command to compile UI assets:
npm run build
Finally add admin dashboard route inside routes/web.php as given below:
//...
Route::get('/dashboard-admin', function () {
return view('dashboard-admin');
})->middleware(['auth','admin']);
require __DIR__.'/auth.php';
Notice that we have attached ‘admin‘ middleware to the above route which will make sure that only those users can access this route who have role as ‘admin‘. You can attach ‘admin‘ middleware to any route to which you want to restrict normal users access. Let’s try it.
First, run PHP development sever by entering following command;
php artisan serv
Then, enter following URL in address bar of the browser;
http://localhost:8000
Now, log in with john@gmail.com (admin role user) and then enter following URL in address bar of the browser;
http://localhost:8000/dashboard-admin
Since the user has ‘admin‘ role then the dashboard-admin will be accessed nicely. Now log off and log in with jane@gmail.com (non-admin role user). And then enter the above URL and notice how you’ll be taken back to previous view with alert message.
1 thought on “Middleware and Component in Laravel app”