Pourquoi l'authentification « maison » est une bombe à retardement
\n\nUn développeur PHP sur deux a déjà écrit son propre système de connexion. Cela semble simple : un formulaire, une vérification d'identifiant, une session. Mais c'est précisément à cette étape « simple » que des millions de sites échouent. Injections SQL, vol de sessions, force brute — des attaques qui transforment votre projet en fuite de données personnelles.
\n\nDans cet article, nous allons détailler l'authentification sécurisée en PHP de A à Z. Pas de magie, seulement des pratiques éprouvées utilisées chez Facebook, GitHub et dans votre framework préféré. Vous apprendrez à hacher correctement les mots de passe, à protéger les sessions contre l'interception et à intégrer des mécanismes modernes comme JWT.
\n\nPrêt ? C'est parti.
\n\n1. Hachage des mots de passe : pourquoi md5() est une condamnation à mort
\n\nPremière règle de sécurité : ne stockez jamais, au grand jamais, les mots de passe en clair. Deuxième règle : n'utilisez pas d'algorithmes obsolètes comme MD5 ou SHA1. Ils se calculent en microsecondes, et n'importe quel étudiant avec un ordinateur portable trouvera votre mot de passe en une heure.
\n\nPHP propose une solution intégrée : les fonctions password_hash() et password_verify(). Elles utilisent bcrypt (ou Argon2 si PHP ≥ 7.2) et ajoutent automatiquement un « sel » — une chaîne aléatoire qui rend chaque hachage unique.
Exemple de hachage correct
\n// Inscription d'un utilisateur\n$password = $_POST['password'];\n$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);\n\n// Enregistrez $hash dans la base de données\n// Pas de sel manuel ! PHP s'en charge tout seul.\n\n\nVérification du mot de passe lors de la connexion
\n// Connexion d'un utilisateur\n$inputPassword = $_POST['password'];\n$storedHash = 'depuis la base de données';\n\nif (password_verify($inputPassword, $storedHash)) {\n // Mot de passe correct — accès autorisé\n} else {\n // Mot de passe incorrect\n}\n\n\nNotez le paramètre cost. Il définit le « coût » de calcul du hachage. Plus le nombre est élevé, plus un attaquant mettra de temps à forcer le mot de passe. Pour 2024, cost = 12 est le juste équilibre entre sécurité et rapidité.
2. Sessions : comment ne pas donner les clés de la maison
\n\nAprès une connexion réussie, on démarre généralement une session. Mais les sessions PHP standard ont des faiblesses : des ID prévisibles, des fuites via l'URL, une fixation de session (session fixation).
\n\nConfiguration sécurisée des sessions
\n// Tout en haut du script, avant tout affichage HTML\nini_set('session.use_only_cookies', 1);\nini_set('session.use_strict_mode', 1);\nini_set('session.cookie_httponly', 1);\nini_set('session.cookie_secure', 1); // HTTPS uniquement\nini_set('session.cookie_samesite', 'Lax');\n\nsession_start();\n\n// Régénérez l'ID de session après la connexion\nif ($login_success) {\n session_regenerate_id(true);\n $_SESSION['user_id'] = $user['id'];\n}\n\n\nCe que nous avons fait :
\n- \n
- use_only_cookies — interdit la transmission de l'ID de session via l'URL (pour éviter le vol via un lien) \n
- use_strict_mode — bloque les sessions non initialisées \n
- httponly — empêche JavaScript d'accéder au cookie de session (protection contre XSS) \n
- secure — le cookie n'est transmis qu'en HTTPS \n
- samesite — protection contre les attaques CSRF par falsification de requêtes intersites \n
Et surtout : régénérez toujours l'ID de session après la connexion. Sinon, un attaquant pourrait préalablement fournir son propre ID de session à l'utilisateur et prendre le contrôle du compte.
\n\n3. Protection CSRF : vérifier que la requête vient bien de vous
\n\nCSRF (Cross-Site Request Forgery) est une attaque où un utilisateur clique sur un lien du type /supprimer-compte?id=1 et, sans le vouloir, exécute une action. Pour l'éviter, utilisez des jetons.
Génération et vérification du jeton CSRF
\n// Génération du jeton (au début de la session ou au chargement du formulaire)\nif (empty(