OAuth 2.0 et autorisation JWT en TypeScript : guide pratique

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : pourquoi OAuth 2.0 et JWT sont la norme de l'autorisation moderne

\n

Dans le développement web moderne, l'authentification et l'autorisation sécurisées sont des composants essentiels de toute application. OAuth 2.0 et JWT (JSON Web Tokens) sont devenus la norme de facto pour la construction de systèmes distribués. OAuth 2.0 fournit un protocole d'accès délégué, tandis que JWT offre un format de token compact et autonome.

\n

Dans cet article, nous allons analyser, à l'aide d'exemples pratiques en TypeScript, comment implémenter le cycle complet d'autorisation : de l'émission des tokens à leur validation et leur renouvellement. Vous apprendrez à protéger les endpoints d'API, à implémenter les refresh tokens et à gérer les erreurs typiques.

\n\n

1. Configuration de base du projet et installation des dépendances

\n

Pour commencer, créons un projet Node.js avec TypeScript. Assurez-vous d'avoir installé Node.js (version 18+) et npm.

\n
mkdir oauth-jwt-typescript\ncd oauth-jwt-typescript\nnpm init -y\nnpm install express cors dotenv jsonwebtoken bcrypt\nnpm install -D typescript @types/express @types/cors @types/jsonwebtoken @types/bcrypt ts-node nodemon\nnpx tsc --init
\n

Configurons tsconfig.json pour fonctionner avec les modules ES et les types stricts. Ajoutons les clés secrètes dans le fichier .env :

\n
ACCESS_TOKEN_SECRET=your-super-secret-access-key\nREFRESH_TOKEN_SECRET=your-super-secret-refresh-key\nACCESS_TOKEN_EXPIRES_IN=15m\nREFRESH_TOKEN_EXPIRES_IN=7d
\n\n

2. Implémentation de la génération et de la vérification des tokens JWT

\n

Créons un utilitaire src/utils/jwt.ts pour la gestion des tokens. Nous utiliserons deux types de tokens : Access Token (à courte durée de vie) et Refresh Token (à longue durée de vie).

\n
import jwt from 'jsonwebtoken';\nimport dotenv from 'dotenv';\n\ndotenv.config();\n\ninterface TokenPayload {\n  userId: string;\n  email: string;\n  role: 'user' | 'admin';\n}\n\nexport const generateAccessToken = (payload: TokenPayload): string => {\n  return jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET!, {\n    expiresIn: process.env.ACCESS_TOKEN_EXPIRES_IN || '15m',\n  });\n};\n\nexport const generateRefreshToken = (payload: TokenPayload): string => {\n  return jwt.sign(payload, process.env.REFRESH_TOKEN_SECRET!, {\n    expiresIn: process.env.REFRESH_TOKEN_EXPIRES_IN || '7d',\n  });\n};\n\nexport const verifyAccessToken = (token: string): TokenPayload => {\n  return jwt.verify(token, process.env.ACCESS_TOKEN_SECRET!) as TokenPayload;\n};\n\nexport const verifyRefreshToken = (token: string): TokenPayload => {\n  return jwt.verify(token, process.env.REFRESH_TOKEN_SECRET!) as TokenPayload;\n};
\n

Remarque : nous utilisons un typage strict pour le payload. Cela garantit que le token contiendra toujours les champs nécessaires.

\n\n

3. Création d'un middleware pour la protection des routes

\n

Implémentons maintenant un middleware qui vérifiera la présence et la validité de l'Access Token dans l'en-tête Authorization. Créons src/middleware/auth.ts :

\n
import { Request, Response, NextFunction } from 'express';\nimport { verifyAccessToken } from '../utils/jwt';\n\nexport interface AuthRequest extends Request {\n  user?: {\n    userId: string;\n    email: string;\n    role: 'user' | 'admin';\n  };\n}\n\nexport const authenticate = (req: AuthRequest, res: Response, next: NextFunction): void => {\n  const authHeader = req.headers['authorization'];\n  const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN\n\n  if (!token) {\n    res.status(401).json({ error: 'Access token is required' });\n    return;\n  }\n\n  try {\n    const decoded = verifyAccessToken(token);\n    req.user = decoded;\n    next();\n  } catch (error) {\n    res.status(403).json({ error: 'Invalid or expired access token' });\n  }\n};\n\nexport const authorizeRole = (...roles: string[]) => {\n  return (req: AuthRequest, res: Response, next: NextFunction): void => {\n    if (!req.user || !roles                

Blogs

Book Recommendations