Middleware Tutorial in Laravel 11

 <?php


namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class UserController extends Controller
{
    public function register(Request $request)
    {
        $data = $request->validate([
            "name" => "required",
            "email" => "required|email",
            "age" => "required",
            "password" => "required|confirmed",
            "role" => "required"
        ]);

        // if above validation form field names like "name","email","password" and database column names both are same
        // then only we can save data in database by passing "$data" variable in create() method direct as shown below :
        $user = User::create($data);

        // when data is created in database at that time the id will return in "$user" variable
        if ($user) {
            return redirect()->route("login");
        }
    }

    public function login(Request $request)
    {
        $credentials = $request->validate([
            "email" => "required",
            "password" => "required"
        ]);

        if (Auth::attempt($credentials)) {
            return redirect()->route("dashboard");
        }
    }

    public function dashboardPage()
    {
        return view("dashboard");
    }

    // check() and guest() both methods are opposite to each other
    // guest() method checks if user not login then only condition will true
    // check() method checks if user login then only condition will true
    public function innerPage()
    {
        return view("inner");
    }

    // Generally when user login at that time session will create and all sessions are stored in storage/framework/sessions folder in Laravel 11
    public function logout()
    {
        Auth::logout(); //Auth::logout() will remove or destroy session
        return view("login");
    }
}
Above File is app\Http\Controllers\UserController File




Below File is app\Http\Middleware\TestUser File
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class TestUser
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        echo "<h3 class='text-primary'>Test User Middleware</h3>";
        return $next($request);
    }
}





Below File is app\Http\Middleware\ValidUser File
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;

class ValidUser
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next, string $role): Response
    {
        echo "<h3 class='text-primary'>We are now in ValidUser Middleware.</h3>";
        echo "<h3 class='text-primary'>$role</h3>";

        if (Auth::check() && Auth::user()->role == $role) {
            return $next($request);
        } else if (Auth::user()->role == "reader") {
            return redirect()->route("user");
        } else {
            return redirect()->route("login");
        }
    }

    public function terminate(Request $request, Response $response): void
    {
        // When user's request completed then after "terminate()" method will call
        echo "<h3 class='text-danger'>We are now Terminating ValidUser Middleware.</h3>";
    }
}





Below File is app\Models\User File
<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;
    public $timestamps = false;
    protected $table = "users";

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = [
        'name',
        'email',
        "age",
        "role",
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
}





Below File is bootstrap\app File
<?php

use App\Http\Middleware\TestUser;
use App\Http\Middleware\ValidUser;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->alias([
            "IsUserValid" => ValidUser::class
        ]);

        // Middleware groups
        // we can use "prependToGroup()" instead of "appendToGroup()" method
        // $middleware->appendToGroup("ok-user",[
        //     ValidUser::class,
        //     TestUser::class
        // ]);

        // Global Middleware
        $middleware->append(TestUser::class);

        // If we want to apply multiple Global Middleware simultaneously then we can do as shown below :
        // $middleware->use([
        //     TestUser::class,
        //     ValidUser::class
        // ]);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();





Below File is database\migrations\2024_12_25_055624_create_users_table File
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string("name");
            $table->string("email");
            $table->integer("age");
            $table->string("role");
            $table->string("password");
        });
    }

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





Below File is resources\views\dashboard File
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Dashboard</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-5 mt-5">
                <div class="card">
                    <div class="card-header">
                        <h1>Welcome, {{ Auth::user()->name }}</h1>
                    </div>
                    <div class="card-body">
                        {{ Auth::user() }}
                        <a href="{{ route("inner") }}" class="btn btn-primary mt-5">Go to Inner Page</a>
                        <a href="{{ route("login") }}" class="btn btn-danger mt-5">Logout</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>




Below File is resources\views\inner File
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Inner Page</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-5 mt-5">
                <div class="card">
                    <div class="card-header">
                        <h1>Inner Page</h1>
                    </div>
                    <div class="card-body">
                        <a href="{{ route("dashboard") }}" class="btn btn-primary">Back to Dashboard</a>
                        <a href="{{ route("login") }}" class="btn btn-danger">Logout</a><br><br>
                        @if(auth()->check())
                            Id : {{ auth()->id() }},
                            Name : {{ Auth::user()->name }},
                            Email : {{ Auth::user()->email }},
                            Age : {{ Auth::user()->age }},
                            Role : {{ Auth::user()->role }}
                        @endif
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>





Below File is resources\views\login File
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Login</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-5 mt-5">
                <div class="card">
                    <div class="card-header">
                        <h3>Login</h3>
                    </div>
                    <div class="card-body">
                        <form action="{{ route("loginMatch") }}" method="POST">
                            @csrf
                            <div class="mb-3">
                                <label for="useremail" class="form-label">Email Address</label>
                                <input type="email" value="{{ old("email") }}" name="email" class="form-control @error("email") is-invalid @enderror" id="useremail" placeholder="Enter email"/>
                                <span class="text-danger">
                                    @error("email")
                                        {{ $message }}
                                    @enderror
                                </span>
                            </div>
                            <div class="mb-3">
                                <label for="userpassword" class="form-label">Password</label>
                                <input type="password" value="{{ old("password") }}" name="password" class="form-control @error("password") is-invalid @enderror" id="userpassword" placeholder="Enter password"/>
                                <span class="text-danger">
                                    @error("password")
                                        {{ $message }}
                                    @enderror
                                </span>
                            </div>
                            <button type="submit" class="btn btn-primary">Login</button>
                            <a href="{{ route("welcomeTwo") }}" class="btn btn-secondary">Back</a>
                        </form>
                    </div>

                    @if($errors->any())
                    <div class="alert alert-danger">
                        <ul>
                            @foreach($errors->all() as $error)
                                <li>{{ $error }}</li>
                            @endforeach
                        </ul>
                    </div>
                    @endif
                </div>
            </div>
        </div>
    </div>
</body>
</html>





Below File is resources\views\register File
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Register</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-5 mt-5">
                <div class="card">
                    <div class="card-header">
                        <h3>Register</h3>
                    </div>
                    <div class="card-body">
                        <form action="{{ route("registerSave") }}" method="POST">
                            @csrf
                            <div class="mb-3">
                                <label for="username" class="form-label">Name</label>
                                <input type="text" value="{{ old("name") }}" name="name" class="form-control @error("name") is-invalid @enderror" id="username" placeholder="Enter username"/>
                                <span class="text-danger">
                                    @error("name")
                                        {{ $message }}
                                    @enderror
                                </span>
                            </div>
                            <div class="mb-3">
                                <label for="useremail" class="form-label">Email address</label>
                                <input type="email" value="{{ old("email") }}" name="email" class="form-control @error("email") is-invalid @enderror" id="useremail" placeholder="Enter email"/>
                                <span class="text-danger">
                                    @error("email")
                                        {{ $message }}
                                    @enderror
                                </span>
                            </div>
                            <div class="mb-3">
                                <label for="userage" class="form-label">Age</label>
                                <input type="text" value="{{ old("age") }}" name="age" class="form-control @error("age") is-invalid @enderror" id="userage" placeholder="Enter age"/>
                                <span class="text-danger">
                                    @error("age")
                                        {{ $message }}
                                    @enderror
                                </span>
                            </div>
                            <div class="mb-3">
                                <label for="userpassword" class="form-label">Password</label>
                                <input type="password" value="{{ old("password") }}" name="password" class="form-control @error("password") is-invalid @enderror" id="userpassword" placeholder="Enter password"/>
                                <span class="text-danger">
                                    @error("password")
                                        {{ $message }}
                                    @enderror
                                </span>
                            </div>
                            <div class="mb-3">
                                <label for="userpassword-confirm" class="form-label">Confirm Password</label>
                                <input type="password" value="{{ old("password_confirmation") }}" name="password_confirmation" class="form-control @error("password-confirmation") is-invalid @enderror" id="userpassword-confirm" placeholder="Enter confirm password"/>
                                <span class="text-danger">
                                    @error("password_confirmation")
                                        {{ $message }}
                                    @enderror
                                </span>
                            </div>
                            <div class="mb-3">
                                <label for="userrole" class="form-label">Role</label>
                                <input type="text" value="{{ old("role") }}" name="role" class="form-control @error("role") is-invalid @enderror" id="userrole" placeholder="Enter role"/>
                                <span class="text-danger">
                                    @error("role")
                                        {{ $message }}
                                    @enderror
                                </span>
                            </div>
                            <button type="submit" class="btn btn-primary">Register</button>
                            <a href="{{ route("welcomeTwo") }}" class="btn btn-secondary">Back</a>
                        </form>
                    </div>

                    @if($errors->any())
                    <div class="card-footer text-body-secondary">
                        <div class="alert alert-danger">
                            <ul>
                                @foreach($errors->all() as $error)
                                    <li>{{ $error }}</li>
                                @endforeach
                            </ul>
                        </div>
                    </div>
                    @endif
                </div>
            </div>
        </div>
    </div>
</body>
</html>





Below File is resources\views\user File
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Readers Page</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-5 mt-5">
                <div class="card">
                    <div class="card-header">
                        <h3>Readers Page</h3>
                    </div>
                    <div class="card-body">
                        Hello, Reader
                        <a href="{{ route("logout") }}" class="btn btn-danger">Logout</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>





Below File is resources\views\welcomeTwo File
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>welcomeTwo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-5 mt-5">
                <div class="card">
                    <div class="card-header">
                        <h1 class="mb-5">Laravel Authentication</h1>
                    </div>
                    <div class="card-body">
                        <a href="{{ route("register") }}" class="btn btn-primary">Register</a>
                        <a href="{{ route("login") }}" class="btn btn-primary">Login</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>




Below File is routes\web File
<?php

use App\Http\Controllers\UserController;
use App\Http\Middleware\TestUser;
use App\Http\Middleware\ValidUser;
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::get("/user", function(){
    return view("user");
})->name("user");

Route::view("welcomeTwo", "welcomeTwo")->name("welcomeTwo");

Route::view("/register", "register")->name("register");

Route::view("/login", "login")->name("login");

Route::controller(UserController::class)->group(function () {
    Route::post("registerSave", "register")->name("registerSave");
    Route::post("loginMatch", "login")->name("loginMatch");

    Route::get("dashboard", "dashboardPage")->name("dashboard");
    Route::get("dashboard/inner", "innerPage")->name("inner");

    // Below is "Route Middleware"
    // we can pass value role "admin" to check condition as shown below :
    // Route::get("dashboard", "dashboardPage")->name("dashboard")->middleware(["IsUserValid:admin", TestUser::class]);
    // Route::get("dashboard/inner", "innerPage")->name("inner")->middleware(["IsUserValid:admin", TestUser::class]);


    // Below "auth" is laravel's own in-built middleware
    // Route::get("dashboard", "dashboardPage")->name("dashboard")->middleware(["auth","IsUserValid:admin"]);
    // Route::get("dashboard/inner", "innerPage")->name("inner")->middleware(["auth","IsUserValid:admin"]);


    // Making group of Middleware, Below is "Route Middleware"
    // Route::middleware(["ok-user"])->group(function () {
    //     Route::get("dashboard", "dashboardPage")->name("dashboard");
    //     Route::get("dashboard/inner", "innerPage")->name("inner")->withoutMiddleware([TestUser::class]);    //Removing specific middleware from any specific route
    // });

    // Making group of withoutMiddleware, Below is "Route Middleware"
    // Route::withoutMiddleware([TestUser::class])->group(function () {
    //     Route::get("dashboard/inner", "innerPage")->name("inner");
    // });

    Route::get("logout", "logout")->name("logout");
});












Comments

Popular posts from this blog

Eloquent Many to Many Relationship Tutorial in Laravel 11

Eloquent with JSON Data Columns Tutorial in Laravel 11

Blade Template Tutorial Three Template Inheritance in Laravel 11