Auth
L'authentification basée sur les sessions, le formulaire de connexion préconstruit et le modèle de plugin Utilisateur provenant de la production.
Nibiru embarque un noyau d’authentification basé sur les sessions (Nibiru\Auth) et un module utilisateurs qui vous offre un formulaire de connexion fonctionnel, une vérification d’autorisation et le schéma de base de données en trois commandes.
Le noyau d’authentification
Section intitulée « Le noyau d’authentification »Auth::auth($login, $password) est l’appel de niveau le plus bas. Il :
- Recherche l’utilisateur par
user_login. - Décrypte le mot de passe stocké en utilisant le sel de
[SECURITY] password_hash. - En cas de correspondance, remplace
$_SESSIONpar['auth' => ['session_id' => …, 'user_id' => …, 'login' => …]].
$auth = new \Nibiru\Auth();if ($auth->auth($_POST['login'], $_POST['password'])) { View::forwardTo('/dashboard');} else { View::assign(['error' => 'Invalid credentials.']);}Le module Utilisateurs
Section intitulée « Le module Utilisateurs »Générer une fois avec la CLI :
./nibiru -m usersExécutez ensuite les migrations correspondantes :
./nibiru -mi localVous avez maintenant :
application/module/users/— le dossier du module.userstable — créée par005-user.sql.Userplugin —Nibiru\Module\Users\Plugin\UseravecisAuthorized(),loginForm(),currentUser().
Un flux de connexion complet
Section intitulée « Un flux de connexion complet »application/controller/loginController.php:
<?phpnamespace Nibiru;use Nibiru\Adapter\Controller;use Nibiru\Module\Users\Plugin\User;
class loginController extends Controller{ private User $user;
public function __construct() { parent::__construct(); $this->user = new User(); }
public function pageAction() { if ($this->user->isAuthorized()) { View::forwardTo('/'); return; } View::assign([ 'title' => 'Sign in', 'loginForm' => $this->user->loginForm(), ]); }
public function submitAction() { if ($_SERVER['REQUEST_METHOD'] !== 'POST') return; $auth = new Auth(); if ($auth->auth($_POST['login'] ?? '', $_POST['password'] ?? '')) { View::forwardTo('/'); } else { View::assign(['error' => 'Invalid login.']); } }
public function logoutAction() { unset($_SESSION['auth']); session_regenerate_id(true); View::forwardTo('/login'); }
public function navigationAction() { JsonNavigation::getInstance()->loadJsonNavigationArray(); }}application/view/templates/login.tpl:
{include 'shared/header.tpl'}<body>{include file="navigation.tpl"}<main class="container"> <h1>{$title}</h1> {if $error}<div class="alert alert-danger">{$error}</div>{/if} {$loginForm nofilter}</main>{include 'shared/footer.tpl'}</body>Form::action="/login/submit" est défini dans loginForm() afin que le formulaire soumette à l’action correcte.
Protection des contrôleurs
Section intitulée « Protection des contrôleurs »Le test simple :
public function pageAction() { if (!$this->user->isAuthorized()) { View::forwardTo('/login'); return; } / ...}Pour les vérifications basées sur le rôle, les applications de démonstration utilisent le plugin Acl du même module :
use Nibiru\Module\Users\Plugin\Acl;
if (!Acl::can('edit', 'documents')) { View::forwardTo('/forbidden'); return;}Les tables acl, user_to_acl, acl-data (migrations 001, 008, 011) forment la base rôle/permission.
Renforcement
Section intitulée « Renforcement »Pour la production, remplacez Auth::auth() par une version renforcée :
namespace Nibiru;use Nibiru\Pdo;
class HardenedAuth{ public function auth(string $login, string $password): bool { $row = Pdo::fetchRow( 'SELECT user_id, user_pass FROM "user" WHERE user_login = :l AND user_account_active = 1', [':l' => $login] ); if (!$row || !password_verify($password, $row['user_pass'])) { return false; } if (password_needs_rehash($row['user_pass'], PASSWORD_ARGON2ID)) { Pdo::update('user', [ 'user_pass' => password_hash($password, PASSWORD_ARGON2ID), ], ['user_id' => $row['user_id']]); } session_regenerate_id(true); $_SESSION['auth'] = [ 'session_id' => session_id(), 'user_id' => $row['user_id'], 'login' => $login, ]; return true; }}Migrer les lignes existantes lors du premier connexion avec password_needs_rehash.
Nibiru ne génère pas les jetons CSRF pour vous. Ajoutez-les vous-même :
public function pageAction() { if (!isset($_SESSION['csrf'])) { $_SESSION['csrf'] = bin2hex(random_bytes(16)); } View::assign(['csrf' => $_SESSION['csrf']]);}
public function submitAction() { if (!hash_equals($_SESSION['csrf'] ?? '', $_POST['csrf'] ?? '')) { http_response_code(419); return; } / ...handle submission...}Intégrez <input type="hidden" name="csrf" value="{$csrf}"> dans votre formulaire.
Connexion par code QR (modèle TPMS)
Section intitulée « Connexion par code QR (modèle TPMS) »Les applications de production incluent une connexion par lien magique basée sur un code QR qui émet des jetons à durée limitée. Le flux :
- L’utilisateur scanne le QR code → l’URL est
/login/token/<jeton-unique>. tokenActionvalide et crée une session.
Le framework dépend déjà de bacon/bacon-qr-code et picqer/php-barcode-generator via Composer, donc vous pouvez afficher des codes QR en ligne :
$writer = new \BaconQrCode\Writer(new \BaconQrCode\Renderer\ImageRenderer( new \BaconQrCode\Renderer\RendererStyle\RendererStyle(220), new \BaconQrCode\Renderer\Image\SvgImageBackEnd()));$svg = $writer->writeString('https://app.example.com/login/token/' . $token);View::assign(['qr' => $svg]);Tracas courantes
Section intitulée « Tracas courantes »$_SESSIONest remplacé, pas fusionné par leAuth::auth()par défaut. Tout ce que vous aviez stocké avant la connexion est perdu. Sauvegardez et restaurez explicitement si nécessaire.- Aucune limitation de taux. Ajoutez Fail2Ban ou un observateur de type middleware.
- Les cookies de session ont besoin de drapeaux. Définissez
session.cookie_secure = 1,session.cookie_httponly = 1etsession.cookie_samesite = "Lax"dans le php.ini pour la production.