Builders Academy
Authentification & Autorisation — JWT, Sessions et OAuth
1 of 2

Chapitre 1 · Leçon 1

JWT Sécurisé

Access tokens courts + Refresh tokens rotatifs

Section 1

Architecture Access/Refresh

Step 1

Pourquoi deux tokens ?

Un access token courte durée (15 min) pour les requêtes API. Un refresh token longue durée (30 jours) stocké en httpOnly cookie pour renouveler l'access token sans se reconnecter.

snippet.typescript

typescript
1/*
2 * Architecture double token
3 *
4 * ACCESS TOKEN (15 min)
5 * - Court : si volé, expire vite
6 * - Dans Authorization header : Bearer <token>
7 * - Signé avec ACCESS_TOKEN_SECRET
8 * - Payload : userId, role, email
9 * - Jamais stocké en localStorage (XSS risk)
10 *
11 * REFRESH TOKEN (30 jours)
12 * - Long : permet de renouveler l'access token
13 * - Stocké en cookie httpOnly Secure SameSite=Strict
14 * - Signé avec REFRESH_TOKEN_SECRET différent
15 * - Hash stocké en base de données (révocable)
16 * - 1 refresh = 1 nouveau refresh (rotation)
17 */
18
19import jwt from "jsonwebtoken";
20import { randomBytes, createHash } from "crypto";
21
22interface JwtPayload {
23  sub: string;   // userId
24  role: string;
25  email: string;
26  iat: number;
27  exp: number;
28}
29
30function generateTokenPair(user: { id: string; role: string; email: string }) {
31  const accessToken = jwt.sign(
32    { sub: user.id, role: user.role, email: user.email },
33    process.env.ACCESS_TOKEN_SECRET!,
34    { expiresIn: "15m" }
35  );
36
37  const refreshTokenRaw = randomBytes(64).toString("hex");
38  const refreshTokenHash = createHash("sha256")
39    .update(refreshTokenRaw)
40    .digest("hex");
41
42  return { accessToken, refreshTokenRaw, refreshTokenHash };
43}

Step 2

Login, refresh et révocation

Implémentation complète du flow d'authentification avec rotation des refresh tokens.

snippet.typescript

typescript
1/*
2 * Architecture double token
3 *
4 * ACCESS TOKEN (15 min)
5 * - Court : si volé, expire vite
6 * - Dans Authorization header : Bearer <token>
7 * - Signé avec ACCESS_TOKEN_SECRET
8 * - Payload : userId, role, email
9 * - Jamais stocké en localStorage (XSS risk)
10 *
11 * REFRESH TOKEN (30 jours)
12 * - Long : permet de renouveler l'access token
13 * - Stocké en cookie httpOnly Secure SameSite=Strict
14 * - Signé avec REFRESH_TOKEN_SECRET différent
15 * - Hash stocké en base de données (révocable)
16 * - 1 refresh = 1 nouveau refresh (rotation)
17 */
18
19import jwt from "jsonwebtoken";
20import { randomBytes, createHash } from "crypto";
21
22interface JwtPayload {
23  sub: string;   // userId
24  role: string;
25  email: string;
26  iat: number;
27  exp: number;
28}
29
30function generateTokenPair(user: { id: string; role: string; email: string }) {
31  const accessToken = jwt.sign(
32    { sub: user.id, role: user.role, email: user.email },
33    process.env.ACCESS_TOKEN_SECRET!,
34    { expiresIn: "15m" }
35  );
36
37  const refreshTokenRaw = randomBytes(64).toString("hex");
38  const refreshTokenHash = createHash("sha256")
39    .update(refreshTokenRaw)
40    .digest("hex");
41
42  return { accessToken, refreshTokenRaw, refreshTokenHash };
43}

Topics and skills covered

  • JWT
  • Auth
  • Security
  • Refresh Tokens
  • bcrypt