validate([ 'email' => ['required', 'email'], 'password' => ['required', 'string'], ]); $this->appliquerLimiteTentatives($request, 'prof:'.$donnees['email']); if (! Auth::guard('web')->attempt($donnees)) { RateLimiter::hit($this->cleLimite($request, 'prof:'.$donnees['email'])); throw ValidationException::withMessages([ 'email' => 'Identifiants incorrects.', ]); } RateLimiter::clear($this->cleLimite($request, 'prof:'.$donnees['email'])); $request->session()->regenerate(); /** @var User $prof */ $prof = Auth::guard('web')->user(); $avaitDejaUneSession = $prof->jeton_session_actif !== null; $request->session()->put('jeton_session_web', $prof->demarreNouvelleSession()); return redirect()->route('mes-classes.index') ->with('session_precedente_fermee', $avaitDejaUneSession); } public function connexionEleve(Request $request): RedirectResponse { $donnees = $request->validate([ 'identifiant' => ['required', 'string'], 'code' => ['required', 'string'], ]); $this->appliquerLimiteTentatives($request, 'eleve:'.$donnees['identifiant']); $succes = Auth::guard('eleve')->attempt([ 'identifiant' => $donnees['identifiant'], 'password' => $donnees['code'], ]); if (! $succes) { RateLimiter::hit($this->cleLimite($request, 'eleve:'.$donnees['identifiant'])); throw ValidationException::withMessages([ 'identifiant' => 'Identifiant ou code secret incorrect.', ]); } RateLimiter::clear($this->cleLimite($request, 'eleve:'.$donnees['identifiant'])); $request->session()->regenerate(); /** @var Eleve $eleve */ $eleve = Auth::guard('eleve')->user(); $eleve->forceFill(['derniere_connexion_a' => now()])->save(); $request->session()->put('jeton_session_eleve', $eleve->demarreNouvelleSession()); return redirect()->route('eleve'); } /** * Connexion directe par QR (à usage unique, voir App\Services\GenerateurCompteEleve). */ public function connexionParQr(Request $request, string $jeton): RedirectResponse { $eleve = Eleve::where('jeton_qr', $jeton)->first(); if ($eleve === null) { abort(404); } $eleve->forceFill(['jeton_qr' => null, 'derniere_connexion_a' => now()])->save(); Auth::guard('eleve')->login($eleve); $request->session()->regenerate(); $request->session()->put('jeton_session_eleve', $eleve->demarreNouvelleSession()); return redirect()->route('eleve'); } public function deconnexion(Request $request): RedirectResponse { if (Auth::guard('web')->check()) { Auth::guard('web')->user()->terminerSession(); Auth::guard('web')->logout(); } if (Auth::guard('eleve')->check()) { Auth::guard('eleve')->user()->terminerSession(); Auth::guard('eleve')->logout(); } $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect()->route('accueil'); } private function cleLimite(Request $request, string $identifiant): string { return 'connexion:'.$identifiant.'|'.$request->ip(); } private function appliquerLimiteTentatives(Request $request, string $identifiant): void { $cle = $this->cleLimite($request, $identifiant); if (RateLimiter::tooManyAttempts($cle, 5)) { $secondes = RateLimiter::availableIn($cle); throw ValidationException::withMessages([ 'identifiant' => "Trop de tentatives. Réessaie dans {$secondes} secondes.", ]); } } }