ল্যারাভেলে মাল্টি লেভেল অথেনটিকেশন

ল্যারাভেলে ডিফল্ট ভাবে ইউজারে কোন লেভেল থাকে না। আমরা কিছু ফিচার শুধু মাত্র এডমিনের জন্য রাখতে চাই। আর কিছু ফিচার রাখতে চাই রেগুলার ইউজারের জন্য। ল্যারাভেল অ্যাপে এমন ফিচার কিভাবে যুক্ত করা যায়, তাই দেখব। আমরা দুইটা লেভেল নিয়ে কাজ করব, admin, user। চাইলে এখানে একাধিক লেভেল নিয়ে কাজ করা যাবে।

শুরুতে আমরা একটা ল্যারাভেল অ্যাপ তৈরি করে নিব। হার্ড অথবা laravel কমান্ড ব্যবহার করে অ্যাপ তৈরি করলে স্টার্টার কিট হিসেবে Laravel Breeze সিলেক্ট করব। কম্পোজার দিয়ে ল্যারাভেল প্রজেক্ট তৈরি করলে breeze ইন্সটল করে নিব।

…create_user_table.php মাইগ্রেশন ফাইলে role নামে নতুন স্কিমা যোগ করব। table->enum('role',['admin','user'])->default('user'); :

        Schema::create('users', function (Blueprint $table) {
            $table->enum('role',['admin','user'])->default('user');
...

seeders ফোল্ডার থেকে DatabaseSeeder.php ফাইলটা এভাবে লিখবঃ

<?php

namespace Database\Seeders;

use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        DB::table('users')->insert([
            //admin
            [
                'name' =>  'Admin',
                'email' => '[email protected]',
                'password' => Hash::make('password'),
                'role' => 'admin',
            ],
            //user
            [
                'name' =>  'User',
                'email' => '[email protected]',
                'password' => Hash::make('password'),
                'role' => 'user',
            ]
        ]);
    }
}

উপরের উদাহরণে সরাসরি ডেটাবেজে টেবিলে ডেটা ইনসার্ট করবে। আমরা চাইলে User Factory ও ব্যবহার করতে পারি এভাবেঃ


        User::factory()
        ->count(2)
        ->state(new Sequence(
            [
                'name' =>  'Admin',
                'email' => '[email protected]',
                'password' => Hash::make('password'),
                'role' => 'admin',
            ],
            [
                'name' =>  'User',
                'email' => '[email protected]',
                'password' => Hash::make('password'),
                'role' => 'user',
            ]
        ))
        ->create();

use Illuminate\Database\Eloquent\Factories\Sequence; ইম্পোর্ট করে নিতে হবে। এবার ডেটাবেজ মাইগ্রেশন এবং সিড করে নিবঃ

php artisan migrate:fresh --seed

ডেটাবেজ যদি আমরা এবার খুলে দেখি, দেখব ইউজার টেবিলে দুইটা ইউজার যুক্ত হয়েছে।

আমাদের একটা মিডেলওয়ার তৈরি করতে হবে। যেন নির্দিষ্ট ইউজার লেভেল চেক করা যায়। তার জন্য Role নামে একটা মিডেলওয়ার তৈরি করে নিবঃ

php artisan make:middleware Role

এই ফাইলটি তৈরি হবে Middleware ফোল্ডারের ভেতর। handle নামে একথা মেথড বিল্টইন থাকবে। যা এভাবে রিরাইট করবঃ

    public function handle(Request $request, Closure $next, $role): Response
    {
        if (auth()->check() && auth()->user()->role === $role) {
            return $next($request);
        }

        abort(403, 'Unauthorized action.');
    }

এখানে নির্দিষ্ট রোলের বাহিরে যদি কেউ কোন কিছু এক্সেস করতে চায়, তাহলে Unauthorized action দেখাবে।

এই Role মিডেলওয়ার রেজিট্রার করতে হবে। আর তা করতে হবে bootstrap>app.php ফাইলে। withMiddleware এর ভেতর নিচের মিডেলওয়ার এলিয়াস যোগ করবঃ

   $middleware->alias([
            'role' => \App\Http\Middleware\Role::class
            ]);

বুঝার সুবিধার জন্য সম্পূর্ণ bootstrap>app.php ফাইলঃ

<?php

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([
            'role' => \App\Http\Middleware\Role::class
            ]);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

ইউজার রোল তৈরি করা শেষ। এবার আমরা এই রোল যে কোন যায়গায় ব্যবহার করতে পারব।

UserController নামে একটা কন্ট্রোলার তৈরি করে নিবঃ

php artisan make:controller UserController

index মেথড এভাবে লিখবঃ

    public function index()
    {
        // Check if the user is authenticated
        if (!auth()->check()) {
            // User is not logged in
            // Show view for guests
            return "You are not logged in";
        }

        // Check the authenticated user's role
        // Show view for admin
        $role = auth()->user()->role;

        if ($role === 'admin') {
            // User is an admin
            return "Logged in as admin";
        } else {
            // User is a regular user
            // Show view for regular user
           return "Logged In as user";
        }
    }

web.php ফাইলে একটা রুট যোগ করবঃ

Route::get('/home',[UserController::class,'index'])->name('user.index');

এখন যদি আপনি রেগুলার ইউজার হিসেবে /home ভিজিট করেন, তাহলে দেখাবে You are not logged in। যদি এডমিন হিসেবে লগিন করে থাকেন, তাহলে দেখাবে Logged in as admin।

নির্দিষ্ট রুটে মিডেলওয়ার যোগ করতে পারিঃ

//admin routes
Route::middleware(['auth','role:admin'])->group(function () {
    Route::get('/admin/home',[UserController::class,'admin'])->name('admin.home');
});

UserController.php ফাইলে নিচের মেথড যোগ করিঃ

    public function admin(){
        return "Admin home.";
      }

লগিন না করে কেউ যদি /admin/home ভিজিট করার চেষ্টা করে, তাহলে তাকে লগিন স্ক্রিনে নিয়ে যাবে। লগিন করলে /admin/home ভিজিট করতে পারবে।

কেউ যদি রেগুলার ইউজার হিসেবে লগিন করে /admin/home ভিজিট করার চেষ্টা করে, তাহলে Unauthorized action পেইজ দেখাবে।

এখানে উদাহরণ গুলো সিম্পল রাখার জন্য আমি স্ট্রিং রিটার্ণ করেছি। আপনি এখানে চাইলে যে কোন ভিউ রিটার্ণ করতে পারেন return view(‘view-name’) এর মাধ্যমে

একই ভাবে আমরা চাইলে user রোলের জন্যও রুট সেট করতে পারি এভাবেঃ

//user routes
Route::middleware(['auth','role:admin'])->group(function () {
    Route::get('/user/home',[UserController::class,'user'])->name('user.home');
});

UserController.php ফাইলে নিচের মেথড যোগ করিঃ

public function user(){

return “User home.”;

}

এখন /user/home শুধু মাত্র রেগুলার ইউজার এক্সেস করতে পারবে।

নির্দিষ্ট ইউজারের পেইজে রিডাইরেক্ট করাঃ

Route::get('/admin', [UserController::class, 'profile'])->name('admin');
Route::get('/user', [UserController::class, 'profile'])->name('user');

উপরের দুইটা রুট খেয়াল করি। কেউ যদি admin হিসেবে লগিন করে, এরপর /user রুট এক্সেস করার চেষ্টা করে, তাকে /admin রুটে রিডাইরেক্ট করে নিবে। এর জন্য আমরা নিচের মত করে মেথড লিখতে পারিঃ

        public function profile()
    {
        if (!auth()->check()) {
            // Redirect to login if not authenticated
            return redirect()->route('login');
        }

        $role = auth()->user()->role;

        // Check if the user is already on their correct profile to avoid infinite redirects

        if ($role === 'admin' && request()->routeIs('admin')) {
            // Render admin profile view
            return "Admin profile";
        }

        if ($role === 'user' && request()->routeIs('user')) {
            // Render user profile view
             return "Regular user profile";
        }

        // Redirect to the correct profile
        if ($role === 'admin') {
            return redirect()->route('admin');
        } else {
            return redirect()->route('user');
        }

    }

এছাড়া আমরা চাইলে এক এক ইউজার রোলের জন্য এক একটা ভিউ দেখাতে পারিঃ

প্রথমে web.php ফাইলে রুট যোগ করে নেইঃ

Route::get(‘/welcome’, [UserController::class, ‘welcome’])->name(‘welcome’);

এরপর UserController.php ফাইলে welcome মেথড এভাবে লিখিঃ

    public function welcome()
    {
        // Check if the user is authenticated
        if (!auth()->check()) {
            // User is not logged in
            // Show view for guests
            return "You are not logged in";
        }

        // Check the authenticated user's role

        $role = auth()->user()->role;

        if ($role === 'admin') {
            // User is an admin
          // Show view for admin
            return "Logged in as admin";
        } else {
            // User is a regular user
            // Show view for regular user
           return "Logged In as user";
        }
    }

ডিফল্ট ভাবে ইউজার রেজিস্ট্রেশন করলে তার রোল হবে user। তো আমরা যদি চাই যে কোন ইউজারকে admin হিসেবে এক্সেস দিতে, তাহলে ডেটাবেজ থেকে user টেবিল এডিট করে নির্দিষ্ট ইউজারের role পরিবর্তন করে admin করা যাবে।

Leave a Reply