Laravel Résumé
Models Migration Relation
Introduction Installation Projet:Structure Strucutre,model,migration Migration,Models,Relation Artisan CLI
Les Relations
BelongsTo HasOne HasMany BelongsToMany HasManyThrough
Exemples des Relations
Relations:oneToMany,ManyToMany... Relations:Exemples
Exercices
Exercice 1 Exercice 2
Controllers Views Routes
Routes,Controller,Model,view
Les Routes
Définir:Routes Routes avec Paramètres Routes nommées Groupes de routes
Les Controllers
Les Controllers Les Contrôleurs de Ressources
Les Vues
Vues et Blade Templates Blade Layouts et Sections Sous-vues Composants et Slots Contrôles de flux
MVC :CRUD
CRUD: Produit CRUD: Etudiant CRUD: Car CRUD,Recherche: Book
Validation
Exemple :Projets
ORM:Eloquent
Exemple :Transport
Api:Laravel +React
Middleware

Seeders & Factories
Exemples :EFM

Authenfication
Queue,job,task
TP:Schools Management
Authenfication:React
Layouts
Exercices





Authentification avec Rôles - Laravel

Étape 1:Configuration de Base

installation des dépendances nécessaires.

# Installation de Laravel UI pour les vues d'authentification
composer require laravel/ui

# Générer les vues d'authentification avec Bootstrap
php artisan ui bootstrap --auth

# Installation des dépendances front-end
npm install
npm run dev

Étape 2: Création des Modèles et des Migrations

Création du modèle Role
app/Models/Role.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\User;

class Role extends Model
{   
    use HasFactory;
    
    protected $primaryKey = "idRole";
    protected $table = "roles";
    protected $fillable = ['name'];

    public function users()
    {
        return $this->hasMany(User::class, 'idRole');
    }
}
Mise à jour du modèle User
app/Models/User.php
<?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;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'prenom',
        'idRole',
        'active',
        'email',
        'password',
    ];

    public function role()
    {
        return $this->belongsTo(Role::class, 'idRole', 'idRole');
    }
    
    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
    ];
}
Création de la migration pour les rôles
php artisan make:migration create_roles_table
database/migrations/xxxx_xx_xx_create_roles_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::create('roles', function (Blueprint $table) {
            $table->id('idRole');
            $table->string('name');
            $table->timestamps();
        });
        
        // Ajout de la colonne idRole à la table users
        Schema::table('users', function (Blueprint $table) {
            $table->unsignedBigInteger('idRole')->nullable()->after('email');
            $table->boolean('active')->default(true)->after('idRole');
            $table->foreign('idRole')->references('idRole')->on('roles');
        });
    }

    public function down()
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropForeign(['idRole']);
            $table->dropColumn(['idRole', 'active']);
        });
        
        Schema::dropIfExists('roles');
    }
};

Étape 3: Création du Seeder pour les Rôles

php artisan make:seeder RoleSeeder
database/seeders/RoleSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class RoleSeeder extends Seeder
{
    public function run()
    {
        DB::table('roles')->insert([
            ['name' => 'Admin'],
            ['name' => 'Editor'],
            ['name' => 'User']
        ]);
    }
}
# Exécuter la migration et le seeder
php artisan migrate
php artisan db:seed --class=RoleSeeder

Étape 4: Création du Middleware pour les Rôles

php artisan make:middleware CheckRole
app/Http/Middleware/CheckRole.php
<?php

namespace App\Http\Middleware;

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

class CheckRole
{
    public function handle(Request $request, Closure $next, ...$roles)
    {
        if (!Auth::check()) {
            return redirect('/login');
        }

        $user = Auth::user();
        $userRole = $user->role->name ?? null;

        if (!in_array($userRole, $roles)) {
            abort(403, 'Accès non autorisé');
        }

        return $next($request);
    }
}
Enregistrement du middleware dans le Kernel
app/Http/Kernel.php
protected $routeMiddleware = [
    // ... autres middlewares
    'role' => \App\Http\Middleware\CheckRole::class,
];

Étape 5: Création des Contrôleurs

Contrôleur principal pour les administrateurs
php artisan make:controller AdminController
app/Http/Controllers/AdminController.php
<?php

namespace App\Http\Controllers;

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

class AdminController extends Controller
{
    public function __construct()
    {
        $this->middleware(['auth', 'role:Admin']);
    }

    public function dashboard()
    {
        $users = User::with('role')->get();
        return view('admin.dashboard', compact('users'));
    }

    public function manageUsers()
    {
        $users = User::with('role')->paginate(10);
        $roles = Role::all();
        return view('admin.users', compact('users', 'roles'));
    }

    public function updateUserRole(Request $request, $id)
    {
        $user = User::findOrFail($id);
        $user->idRole = $request->role_id;
        $user->save();
        
        return redirect()->back()->with('success', 'Rôle mis à jour avec succès');
    }

    public function toggleUserStatus($id)
    {
        $user = User::findOrFail($id);
        $user->active = !$user->active;
        $user->save();
        
        return redirect()->back()->with('success', 'Statut utilisateur mis à jour');
    }
}
Contrôleur pour les éditeurs
php artisan make:controller EditorController
app/Http/Controllers/EditorController.php
<?php

namespace App\Http\Controllers;

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

class EditorController extends Controller
{
    public function __construct()
    {
        $this->middleware(['auth', 'role:Admin,Editor']);
    }

    public function dashboard()
    {
        return view('editor.dashboard');
    }

    public function contentManagement()
    {
        return view('editor.content');
    }
}

Étape 6: Définition des Routes

routes/web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AdminController;
use App\Http\Controllers\EditorController;
use Illuminate\Support\Facades\Auth;

// Routes d'authentification par défaut
Auth::routes();

// Routes protégées par authentification
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

// Routes pour les administrateurs uniquement
Route::prefix('admin')->middleware(['auth', 'role:Admin'])->group(function () {
    Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard');
    Route::get('/users', [AdminController::class, 'manageUsers'])->name('admin.users');
    Route::put('/users/{id}/role', [AdminController::class, 'updateUserRole'])->name('admin.update.user.role');
    Route::put('/users/{id}/status', [AdminController::class, 'toggleUserStatus'])->name('admin.toggle.user.status');
});

// Routes pour les éditeurs et administrateurs
Route::prefix('editor')->middleware(['auth', 'role:Admin,Editor'])->group(function () {
    Route::get('/dashboard', [EditorController::class, 'dashboard'])->name('editor.dashboard');
    Route::get('/content', [EditorController::class, 'contentManagement'])->name('editor.content');
});

// Route pour tous les utilisateurs authentifiés
Route::get('/profile', function () {
    $user = Auth::user();
    return view('profile', compact('user'));
})->middleware('auth')->name('profile');

// Route pour la déconnexion
Route::post('/logout', function () {
    Auth::logout();
    return redirect('/login');
})->middleware('auth')->name('logout');

Étape 7: Création des Vues

Menu de navigation avec gestion des rôles
resources/views/layouts/app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <title>@yield('title', 'Application avec Rôles')</title>
</head>
<body>
    <nav class="navbar navbar-expand-md navbar-dark bg-dark">
        <div class="container">
            <a class="navbar-brand" href="{{ url('/') }}">
                Mon Application
            </a>
            
            <div class="navbar-nav ms-auto">
                @guest
                    <a class="nav-link" href="{{ route('login') }}">Connexion</a>
                    <a class="nav-link" href="{{ route('register') }}">Inscription</a>
                @else
                    <span class="navbar-text me-3">
                        Bonjour, {{ Auth::user()->name }}
                    </span>
                    
                    @if(Auth::user()->role->name === 'Admin')
                        <a class="nav-link" href="{{ route('admin.dashboard') }}">Admin</a>
                    @elseif(Auth::user()->role->name === 'Editor')
                        <a class="nav-link" href="{{ route('editor.dashboard') }}">Éditeur</a>
                    @endif
                    
                    <a class="nav-link" href="{{ route('profile') }}">Profil</a>
                    <form method="POST" action="{{ route('logout') }}" class="d-inline">
                        @csrf
                        <button type="submit" class="btn btn-link nav-link">Déconnexion</button>
                    </form>
                @endguest
            </div>
        </div>
    </nav>

    <main class="py-4">
        @yield('content')
    </main>
</body>
</html>
Vue du tableau de bord administrateur
resources/views/admin/dashboard.blade.php
@extends('layouts.app')

@section('title', 'Tableau de Bord Administrateur')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <h1>Tableau de Bord Administrateur</h1>
            <p>Bienvenue {{ Auth::user()->name }}, vous avez des droits d'administrateur.</p>
            
            <div class="card">
                <div class="card-header">
                    Gestion des Utilisateurs
                </div>
                <div class="card-body">
                    <table class="table">
                        <thead>
                            <tr>
                                <th>Nom</th>
                                <th>Email</th>
                                <th>Rôle</th>
                                <th>Statut</th>
                                <th>Actions</th>
                            </tr>
                        </thead>
                        <tbody>
                            @foreach($users as $user)
                            <tr>
                                <td>{{ $user->name }}</td>
                                <td>{{ $user->email }}</td>
                                <td>{{ $user->role->name ?? 'Aucun' }}</td>
                                <td>
                                    @if($user->active)
                                        <span class="badge bg-success">Actif</span>
                                    @else
                                        <span class="badge bg-danger">Inactif</span>
                                    @endif
                                </td>
                                <td>
                                    <form method="POST" action="{{ route('admin.toggle.user.status', $user->id) }}" class="d-inline">
                                        @csrf
                                        @method('PUT')
                                        <button type="submit" class="btn btn-sm btn-secondary">
                                            @if($user->active) Désactiver @else Activer @endif
                                        </button>
                                    </form>
                                </td>
                            </tr>
                            @endforeach
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
Vue du tableau de bord éditeur
resources/views/editor/dashboard.blade.php
@extends('layouts.app')

@section('title', 'Tableau de Bord Éditeur')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <h1>Tableau de Bord Éditeur</h1>
            <p>Bonjour {{ Auth::user()->name }}, vous avez des droits d'édition.</p>
            
            <div class="card">
                <div class="card-body">
                    <a href="{{ route('editor.content') }}" class="btn btn-primary">
                        Gérer le Contenu
                    </a>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Étape 8: Configuration Supplémentaire

Mise à jour du contrôleur d'inscription pour assigner un rôle par défaut
app/Http/Controllers/Auth/RegisterController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

class RegisterController extends Controller
{
    use RegistersUsers;

    protected $redirectTo = RouteServiceProvider::HOME;

    public function __construct()
    {
        $this->middleware('guest');
    }

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'prenom' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }

    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'prenom' => $data['prenom'],
            'email' => $data['email'],
            'idRole' => 3, // Rôle par défaut: User
            'active' => true,
            'password' => Hash::make($data['password']),
        ]);
    }
}
Test de l'application
# Lancer le serveur
php artisan serve

# Accéder aux différentes pages :
# - http://127.0.0.1:8000/register - Inscription
# - http://127.0.0.1:8000/login - Connexion
# - http://127.0.0.1:8000/admin/dashboard - Tableau de bord admin (rôle requis)
# - http://127.0.0.1:8000/editor/dashboard - Tableau de bord éditeur (rôle requis)

Notes de Sécurité Importantes

  • Valider toujours les rôles côté serveur, jamais uniquement côté client
  • Implémenter des vérifications d'autorisation pour chaque opération sensible
  • Utiliser des politiques (Policies) pour une logique d'autorisation complexe
  • Vérifier régulièrement les affectations de rôles et les permissions
  • Assurer que les changements de rôle sont journalisés pour le suivi de sécurité
  • Protéger les routes sensibles avec des middlewares appropriés