Cours Next.js · Module 7: Authentification et autorisation
Stratégies d'authentification
Dans cette leçon6
Dans les parties précédentes, nous avons vu les bases de l'authentification et mis en place une autorisation simple à l'aide de JWT. Nous allons maintenant explorer les différentes stratégies d'authentification que tu peux appliquer dans tes applications.
Authentification basée sur les jetons vs. basée sur les sessions
Les deux grandes approches de l'authentification sont :
1. Authentification basée sur les sessions (Session-based Authentication)
Dans cette approche, le serveur conserve l'état de la session pour chaque utilisateur connecté :
1// Example session configuration in Express
2import express from 'express';
3import session from 'express-session';
4
5const app = express();
6
7app.use(session({
8 secret: 'cle-secrete-session',
9 resave: false,
10 saveUninitialized: false,
11 cookie: { secure: true, maxAge: 3600000 } // 1 godzina
12}));
13
14app.post('/login', (req, res) => {
15 // Après une authentification réussie
16 req.session.authenticated = true;
17 req.session.userId = user.id;
18 res.send({ success: true });
19});
20
21app.get('/protected', (req, res) => {
22 if (req.session.authenticated) {
23 // L'utilisateur possède une session valide
24 res.send('Données protégées');
25 } else {
26 res.status(401).send('Accès refusé');
27 }
28});Avantages :
- Facilité de mise en œuvre et de maintenance
- Possibilité d'invalider immédiatement une session
- Ne nécessite pas de traitement supplémentaire côté client
Inconvénients :
- Charge serveur (stockage de l'état)
- Problèmes d'évolutivité dans une architecture distribuée
- Difficultés de mise en œuvre pour les applications mobiles
2. Authentification basée sur les jetons (Token-based Authentication)
Dans cette approche, le serveur génère un jeton que le client stocke et envoie à chaque requête :
1// Example JWT implementation in Express
2import express from 'express';
3import jwt from 'jsonwebtoken';
4
5const app = express();
6const JWT_SECRET = 'cle-secrete-jwt';
7
8app.post('/login', (req, res) => {
9 // Après une authentification réussie
10 const token = jwt.sign(
11 { userId: user.id, email: user.email },
12 JWT_SECRET,
13 { expiresIn: '1h' }
14 );
15
16 res.send({ token });
17});
18
19// Middleware de vérification du jeton
20const verifyToken = (req, res, next) => {
21 const token = req.headers.authorization?.split(' ')[1];
22
23 if (!token) {
24 return res.status(401).send("Jeton d'autorisation manquant");
25 }
26
27 try {
28 const decoded = jwt.verify(token, JWT_SECRET);
29 req.user = decoded;
30 next();
31 } catch (error) {
32 return res.status(401).send('Jeton invalide');
33 }
34};
35
36app.get('/protected', verifyToken, (req, res) => {
37 res.send('Données protégées');
38});Avantages :
- Sans état (stateless) - mise à l'échelle plus facile
- Fonctionne bien dans les applications mobiles et les SPA
- Possibilité de stocker des informations supplémentaires dans le jeton
Inconvénients :
- Plus difficile d'invalider un jeton avant son expiration
- Vulnérabilité au vol (si des mesures de sécurité adéquates ne sont pas appliquées)
- Des jetons plus volumineux peuvent augmenter la charge réseau
OAuth 2.0 et authentification sociale
OAuth 2.0 est un standard de protocole d'autorisation qui permet aux applications d'accéder aux ressources d'un utilisateur sur un autre serveur sans partager les identifiants.
Mise en œuvre de l'authentification via Google
1// Mise en œuvre d'OAuth avec Google dans Express et Passport
2import express from 'express';
3import passport from 'passport';
4import { Strategy as GoogleStrategy } from 'passport-google-oauth20';
5
6const app = express();
7
8// Configuration de Passport
9passport.use(new GoogleStrategy({
10 clientID: 'TON_GOOGLE_CLIENT_ID',
11 clientSecret: 'TON_GOOGLE_CLIENT_SECRET',
12 callbackURL: 'http://localhost:3000/auth/google/callback'
13 },
14 function(accessToken, refreshToken, profile, done) {
15 // Trouver ou créer l'utilisateur dans la base de données
16 User.findOrCreate({ googleId: profile.id }, function (err, user) {
17 return done(err, user);
18 });
19 }
20));
21
22// Routes d'authentification
23app.get('/auth/google',
24 passport.authenticate('google', { scope: ['profile', 'email'] }));
25
26app.get('/auth/google/callback',
27 passport.authenticate('google', { failureRedirect: '/login' }),
28 (req, res) => {
29 // Redirection après une authentification réussie
30 res.redirect('/dashboard');
31 }
32);Authentification multifacteur (MFA)
L'authentification multifacteur (MFA) renforce la sécurité en demandant à l'utilisateur de fournir deux preuves d'identité ou plus.
Exemple de mise en œuvre MFA avec TOTP (Time-based One-Time Password)
1// Implementacja 2FA z TOTP w Node.js
2import express from 'express';
3import speakeasy from 'speakeasy';
4import QRCode from 'qrcode';
5
6const app = express();
7app.use(express.json());
8
9// Génération d'une clé secrète pour l'utilisateur
10app.post('/generate-2fa', (req, res) => {
11 const secret = speakeasy.generateSecret({
12 name: 'MonApplication:' + req.user.email
13 });
14
15 // Enregistre secret.base32 dans la base de données pour cet utilisateur
16 saveUserSecret(req.user.id, secret.base32);
17
18 // Génère le code QR
19 QRCode.toDataURL(secret.otpauth_url, (err, imageUrl) => {
20 if (err) {
21 return res.status(500).send('Erreur de génération du code QR');
22 }
23
24 res.json({
25 secret: secret.base32,
26 qrCode: imageUrl
27 });
28 });
29});
30
31// Vérification du code à usage unique
32app.post('/verify-2fa', (req, res) => {
33 const { token } = req.body;
34
35 // Récupère le secret de l'utilisateur depuis la base de données
36 const userSecret = getUserSecret(req.user.id);
37
38 const verified = speakeasy.totp.verify({
39 secret: userSecret,
40 encoding: 'base32',
41 token: token
42 });
43
44 if (verified) {
45 // Active la 2FA pour l'utilisateur dans la base de données
46 enableUser2FA(req.user.id);
47 res.json({ success: true });
48 } else {
49 res.status(400).json({ success: false, message: 'Code invalide' });
50 }
51});Single Sign-On (SSO)
Le Single Sign-On est un processus d'authentification qui permet à un utilisateur d'accéder à plusieurs applications après une seule connexion.
Mise en œuvre du SSO avec SAML
1// Example SAML SSO implementation in Express
2import express from 'express';
3import passport from 'passport';
4import { Strategy as SAMLStrategy } from 'passport-saml';
5
6const app = express();
7
8passport.use(new SAMLStrategy({
9 path: '/login/callback',
10 entryPoint: 'https://sso.example.com/saml2/idp/SSOService.php',
11 issuer: 'mon-application',
12 cert: 'IDENTITY_PROVIDER_CERTIFICATE'
13}, (profile, done) => {
14 // Trouver ou créer l'utilisateur dans la base de données
15 return done(null, {
16 id: profile.nameID,
17 email: profile.email,
18 name: profile.displayName
19 });
20}));
21
22app.get('/login',
23 passport.authenticate('saml', { failureRedirect: '/login/fail' }),
24 (req, res) => res.redirect('/')
25);
26
27app.post('/login/callback',
28 passport.authenticate('saml', { failureRedirect: '/login/fail' }),
29 (req, res) => res.redirect('/')
30);Bonnes pratiques de sécurité pour l'authentification
Mots de passe sûrs
- Exige des mots de passe forts (longueur, complexité)
- Ne stocke que des mots de passe chiffrés (utilise des algorithmes solides comme bcrypt)
- Mets en place une limite de tentatives de connexion
Sécurité des jetons
- Stocke les jetons JWT de manière sûre (cookies HttpOnly)
- Utilise de courtes durées de validité pour les jetons
- Mets en place la rotation et l'invalidation des jetons
Transport
- Utilise toujours HTTPS pour transmettre les identifiants
- Mets en place le HSTS (HTTP Strict Transport Security)
- Sécurise les cookies avec les attributs Secure et SameSite
Règles générales
- Réalise régulièrement des audits de sécurité
- Mets en place la journalisation et la surveillance de l'activité
- Applique toujours le principe du moindre privilège
Résumé
Le choix de la bonne stratégie d'authentification dépend de nombreux facteurs, tels que :
- Les exigences de sécurité de l'application
- Le public cible
- Le type d'application (mobile, web, hybride)
- L'évolutivité et les performances
Souviens-toi que la sécurité de l'authentification est un processus continu qui demande des mises à jour régulières et une adaptation aux nouvelles menaces et aux nouveaux standards de sécurité.
Dans les prochaines leçons, nous passerons à la mise en œuvre de mécanismes d'autorisation avancés et à la gestion des permissions des utilisateurs.
Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. NextAuth.js, c'est :
2. JWT (jeton Web JSON), c'est :
Tâches pratiques dans le jeu
- Tri vertical
Place les étapes du flux Authorization Code d'OAuth 2.0 :
- Clique dans l'ordre
Place la syntaxe de déstructuration de useSession dans NextAuth