Skip to content

Authentification JWT

JSON Web Token (JWT) est un standard ouvert qui définit un moyen compact et indépendant de transmettre des informations entre les parties sous forme d'objet JSON.

Comment fonctionne JWT

  1. Création (Sign) :

    • Lorsque l'utilisateur se connecte avec succès, le serveur crée un JWT en utilisant un algorithme de signature (comme HMAC SHA256) et une clé secrète.
    • Le JWT consiste en trois parties: Header, Payload, et Signature.
    • Header : Contient le type de token et l'algorithme de chiffrement utilisé.
    • Payload : Contient les revendications (claims), qui sont des affirmations sur l'utilisateur et d'autres données.
    • Signature : Utilisée pour vérifier que le message n'a pas été modifié.
  2. Transmission :

    • Le JWT créé est ensuite renvoyé au client, qui le stocke et l'inclut dans les en-têtes d'autorisation de ses requêtes subséquentes au serveur.
  3. Vérification (Verify) :

    • À la réception d'une requête contenant un JWT, le serveur vérifie la validité du token en utilisant la même clé secrète qu'il a utilisée pour le créer.
    • Si le token est valide, la requête est traitée.
    • Si le token est invalide, la requête est rejetée.

jwt.sign():

La méthode jwt.sign() crée un nouveau token. Elle prend trois arguments:

  1. Payload : Les données que vous voulez inclure dans le token.
  2. Secret : Une chaîne de caractères secrète utilisée pour signer le token.
  3. Options : Un objet qui peut contenir diverses options, telles que expiresIn pour définir la durée de vie du token.
javascript
const token = jwt.sign({ userId: 123 }, 'secretKey', { expiresIn: '1h' });
const token = jwt.sign({ userId: 123 }, 'secretKey', { expiresIn: '1h' });

jwt.verify():

La méthode jwt.verify() décode et vérifie un token. Elle prend trois arguments :

  1. Token : Le token JWT à vérifier.
  2. Secret : La même chaîne secrète utilisée pour créer le token.
  3. Callback (optionnel) : Une fonction de rappel qui sera appelée une fois que la vérification est terminée.
javascript
try {
  const decoded = jwt.verify(token, 'secretKey');
  console.log(decoded); // affiche le payload du token
} catch (err) {
  console.error('Token non valide');
}
try {
  const decoded = jwt.verify(token, 'secretKey');
  console.log(decoded); // affiche le payload du token
} catch (err) {
  console.error('Token non valide');
}

Secret Token:

Le secretToken est une chaîne de caractères secrète utilisée pour signer et vérifier les JWT. Il est crucial de garder ce secret confidentiel et sécurisé, car quiconque le connaît peut créer et vérifier des tokens, exposant ainsi votre application à des risques de sécurité.

Initialisation du Projet

Commencez par initialiser un nouveau projet Node.js et installer les paquets nécessaires.

sh
mkdir projetJWT
cd projetJWT
npm init -y
npm install express jsonwebtoken
mkdir projetJWT
cd projetJWT
npm init -y
npm install express jsonwebtoken

Créez un fichier app.js.

Étape 1: Configuration de Base

Dans app.js, configurez votre application Express et ajoutez une route de base.

javascript
import express from 'express';
import jwt from 'jsonwebtoken';

const app = express();
app.use(express.json());

app.get('/', (req, res) => {
  res.send('Bienvenue sur notre serveur Express!');
});

const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Le serveur tourne sur http://localhost:${PORT}`);
});
import express from 'express';
import jwt from 'jsonwebtoken';

const app = express();
app.use(express.json());

app.get('/', (req, res) => {
  res.send('Bienvenue sur notre serveur Express!');
});

const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Le serveur tourne sur http://localhost:${PORT}`);
});

Étape 2: Créer une Route de Login

Créez une route de login qui génère un JWT lorsqu'un utilisateur se connecte avec succès.

javascript
const secretKey = 'maCleSecrete';

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  if (username && password) {
    // Dans une application réelle, vous vérifierez ces données contre une base de données
    const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).send('Nom d’utilisateur ou mot de passe incorrect');
  }
});
const secretKey = 'maCleSecrete';

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  if (username && password) {
    // Dans une application réelle, vous vérifierez ces données contre une base de données
    const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).send('Nom d’utilisateur ou mot de passe incorrect');
  }
});

Sécurité

Les JSON Web Tokens (JWT) sont encodés et non chiffrés, ce qui signifie que bien qu'ils soient convertis en une chaîne de caractères qui semble être du texte brut aléatoire, leur contenu peut être décodé et lu facilement à l'aide de divers outils en ligne, tels que jwt.io.

Les JWT sont souvent utilisés pour stocker des informations telles que l'ID de l'utilisateur ou son rôle, qui sont utilisées pour prendre des décisions concernant l'autorisation sur le serveur. Cependant, étant donné que le contenu d'un JWT peut être décodé, il est crucial de ne jamais y stocker d'informations sensibles ou confidentielles telles que les mots de passe, numéros de sécurité sociale, ou d'autres données personnelles.

Si vous avez besoin de transmettre des informations sensibles de manière sécurisée, vous devriez plutôt utiliser des méthodes de chiffrement, qui transforment les données en un format qui ne peut être lu que par quelqu'un qui possède la clé de chiffrement correcte, plutôt que simplement de l'encodage, qui peut être décodé par n'importe qui.

De plus, les tokens JWT sont souvent stockés dans les cookies ou le local storage côté client. Bien que cela soit pratique, cela expose aussi les utilisateurs à des risques potentiels, tels que les attaques XSS (Cross-Site Scripting) et CSRF (Cross-Site Request Forgery). Pour cette raison, il est essentiel d'appliquer des mesures de sécurité supplémentaires, telles que l'utilisation de cookies sécurisés et HttpOnly, et de mettre en œuvre des politiques de sécurité de contenu pour minimiser le risque d'attaques XSS.

Étape 3: Créer un Middleware d'Authentification JWT

Créez un middleware qui vérifie le token JWT sur les routes sécurisées.

javascript
const jwtMiddleware = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(403).send('Accès refusé. Token non fourni.');

  try {
    const decoded = jwt.verify(token, secretKey);
    req.user = decoded;
    next();
  } catch (exception) {
    res.status(400).send('Token non valide.');
  }
};
const jwtMiddleware = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(403).send('Accès refusé. Token non fourni.');

  try {
    const decoded = jwt.verify(token, secretKey);
    req.user = decoded;
    next();
  } catch (exception) {
    res.status(400).send('Token non valide.');
  }
};

Étape 4: Protéger les Routes avec le Middleware JWT

Créez une route protégée et utilisez le middleware pour la protéger.

javascript
app.get('/protected', jwtMiddleware, (req, res) => {
  res.send('Bienvenue dans la zone protégée!');
});
app.get('/protected', jwtMiddleware, (req, res) => {
  res.send('Bienvenue dans la zone protégée!');
});

Étape 5: Tester l'Application

Maintenant, testez votre application. Lancez votre serveur :

sh
node app.js
node app.js

Utilisez un outil comme Postman ou cURL pour envoyer des requêtes à votre serveur.

  1. Login:

    • Envoyez une requête POST à http://localhost:3000/login avec un body JSON:
      json
      {
        "username": "user",
        "password": "password"
      }
      {
        "username": "user",
        "password": "password"
      }
    • Vous devriez recevoir un token en réponse.
  2. Accéder à une Route Protégée:

    • Avec le token reçu, envoyez une requête GET à http://localhost:3000/protected avec un header Authorization :
      Authorization: Bearer YOUR_JWT_TOKEN
      Authorization: Bearer YOUR_JWT_TOKEN
    • Vous devriez avoir accès à la route protégée si le token est valide.

Code complet:

javascript
import express from 'express';
import jwt from 'jsonwebtoken';

const app = express();
app.use(express.json()); // pour parser le JSON dans les requêtes entrantes

// Clé secrète pour signer les JWT
const secretKey = 'maCleSecrete';

// Middleware pour vérifier les JWT
const jwtMiddleware = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(403).send('Accès refusé. Token non fourni.');

  try {
    const decoded = jwt.verify(token, secretKey);
    req.user = decoded;
    next();
  } catch (exception) {
    res.status(400).send('Token non valide.');
  }
};

// Route de base
app.get('/', (req, res) => {
  res.send('Bienvenue sur notre serveur Express!');
});

// Route de login pour obtenir un JWT
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  if (username && password) {
    // Dans une application réelle, vous vérifierez ces données contre une base de données
    const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).send('Nom d’utilisateur ou mot de passe incorrect');
  }
});

// Route protégée avec le middleware JWT
app.get('/protected', jwtMiddleware, (req, res) => {
  res.send('Bienvenue dans la zone protégée!');
});

// Démarrer le serveur
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Le serveur tourne sur http://localhost:${PORT}`);
});
import express from 'express';
import jwt from 'jsonwebtoken';

const app = express();
app.use(express.json()); // pour parser le JSON dans les requêtes entrantes

// Clé secrète pour signer les JWT
const secretKey = 'maCleSecrete';

// Middleware pour vérifier les JWT
const jwtMiddleware = (req, res, next) => {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(403).send('Accès refusé. Token non fourni.');

  try {
    const decoded = jwt.verify(token, secretKey);
    req.user = decoded;
    next();
  } catch (exception) {
    res.status(400).send('Token non valide.');
  }
};

// Route de base
app.get('/', (req, res) => {
  res.send('Bienvenue sur notre serveur Express!');
});

// Route de login pour obtenir un JWT
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  if (username && password) {
    // Dans une application réelle, vous vérifierez ces données contre une base de données
    const token = jwt.sign({ username }, secretKey, { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).send('Nom d’utilisateur ou mot de passe incorrect');
  }
});

// Route protégée avec le middleware JWT
app.get('/protected', jwtMiddleware, (req, res) => {
  res.send('Bienvenue dans la zone protégée!');
});

// Démarrer le serveur
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Le serveur tourne sur http://localhost:${PORT}`);
});