Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🔐
Intermediaire 25 min NestJS

Authentification dans NestJS

Pourquoi Authentification dans NestJS ?

L'authentification est un élément clé des applications modernes, garantissant que seuls les utilisateurs autorisés peuvent accéder aux ressources protégées. Dans le contexte professionnel, une authentification efficace permet de maintenir la sécurité et l'intégrité des données. Un cas concret est un site web de gestion de projet, où seules les tâches assignées à un utilisateur devraient être visibles.

Prerequis

  • Connaissance de base en JavaScript et TypeScript
  • Compréhension de NestJS et son architecture (Modules, Controllers, Services)
  • Familiarité avec le concept de guards (gardiens) dans NestJS
  • Un environnement de développement Node.js installé (version recommandée : 14.0+)

Concepts fondamentaux

1. Guards (Gardiens)

Un guard est un mécanisme pour vérifier les conditions d'autorisation avant que le handler (la fonction qui gère la requête) ne soit exécuté. NestJS utilise les guards pour implémenter l'authentification.

// auth.guard.ts

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';

@Injectable()
export class AuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
    // Vérifiez ici si l'utilisateur est authentifié
    const request = context.switchToHttp().getRequest();
    if (request.isAuthenticated()) {
      return true;
    }
    return false;
  }
}

2. Strategies d'authentification

Une stratégie d'authentification définit comment un utilisateur peut être authentifié. NestJS prend en charge plusieurs stratégies comme JWT, OAuth2, etc.

// jwt.strategy.ts

import { Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: (req) => req.headers.authorization.split(' ')[1],
      ignoreExpiration: false,
      secretOrKey: 'your-secret-key',
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}

3. Middleware d'authentification

Un middleware est une fonction qui s'exécute avant le traitement de la requête. Il peut être utilisé pour ajouter des informations d'authentification dans le contexte de la requête.

// auth.middleware.ts

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    // Vérifiez ici si l'utilisateur est authentifié
    if (req.headers.authorization) {
      next();
    } else {
      res.status(401).send('Unauthorized');
    }
  }
}

Mise en pratique : projet fil rouge

Étape 1 : Création du projet NestJS

nest new auth-project
cd auth-project

Étape 2 : Installation des dépendances

npm install --save @nestjs/passport passport passport-jwt jsonwebtoken

Étape 3 : Configuration de la stratégie JWT

Créez un fichier jwt.strategy.ts dans le dossier src/auth.

// src/auth/jwt.strategy.ts

import { Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor() {
    super({
      jwtFromRequest: (req) => req.headers.authorization.split(' ')[1],
      ignoreExpiration: false,
      secretOrKey: 'your-secret-key',
    });
  }

  async validate(payload: any) {
    return { userId: payload.sub, username: payload.username };
  }
}

Étape 4 : Création du module d'authentification

Créez un fichier auth.module.ts dans le dossier src/auth.

// src/auth/auth.module.ts

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';

@Module({
  providers: [AuthService, JwtStrategy],
})
export class AuthModule {}

Étape 5 : Configuration de la stratégie JWT dans le module principal

Modifiez app.module.ts pour inclure le module d'authentification.

// src/app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from './auth/auth.module';

@Module({
  imports: [AuthModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Étape 6 : Création d'un service d'authentification

Créez un fichier auth.service.ts dans le dossier src/auth.

// src/auth/auth.service.ts

import { Injectable } from '@nestjs/common';
import * as jwt from 'jsonwebtoken';

@Injectable()
export class AuthService {
  async generateToken(userId: number, username: string): Promise<string> {
    const payload = { sub: userId, username };
    return jwt.sign(payload, 'your-secret-key', { expiresIn: '1h' });
  }
}

Étape 7 : Création d'un controller pour les authentifiations

Créez un fichier auth.controller.ts dans le dossier src/auth.

// src/auth/auth.controller.ts

import { Controller, Post, Body, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { JwtStrategy } from './jwt.strategy';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @Post('login')
  async login(@Body() body): Promise<{ token: string }> {
    const userId = 1; // ID de l'utilisateur fictif
    const username = 'user'; // Nom d'utilisateur fictif
    const token = await this.authService.generateToken(userId, username);
    return { token };
  }
}

Étape 8 : Ajout du guard d'authentification à un controller

Ajoutez le guard JwtStrategy au controlleur qui nécessite une authentification.

// src/tasks/tasks.controller.ts

import { Controller, Get, UseGuards } from '@nestjs/common';
import { JwtStrategy } from '../auth/jwt.strategy';

@Controller('tasks')
@UseGuards(JwtStrategy)
export class TasksController {
  @Get()
  getTasks() {
    return 'Liste des tâches';
  }
}

Erreurs frequentes et debugging

Erreur 1 : JWT invalide

// ❌ Mauvais
const token = 'invalid-jwt-token';

// ✅ Correct
const token = 'your-valid-jwt-token';

Erreur 2 : Strategy non définie

// ❌ Mauvais
import { Strategy } from 'passport-jwt';

// ✅ Correct
import { PassportStrategy } from '@nestjs/passport';

Erreur 3 : Port non défini

// ❌ Mauvais
const PORT = process.env.PORT || '3000';

// ✅ Correct
const PORT = parseInt(process.env.PORT, 10) || 3000;

Pour aller plus loin

1. Sécurité des tokens JWT

En savoir plus sur les bonnes pratiques pour sécuriser les tokens JWT.

2. Authentification OAuth2

Explorer l'authentification OAuth2 pour une meilleure sécurité et flexibilité.

3. Throttling (Throttlement)

Ajouter un système de limitation des requêtes pour prévenir les attaques par déni de service.

Défi pratique

Implémenter un système d'enregistrement et de connexion utilisateurs avec des tokens JWT.

Besoin d'aide sur NestJS ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment configurer l'authentification JWT avec NestJS ?
Pour configurer l'authentification JWT, vous devez d'abord installer le package `@nestjs/jwt` et `jsonwebtoken`. Ensuite, vous pouvez créer un service pour gérer les tokens JWT et un middleware pour vérifier l'authentification des requêtes.
Quelles sont les meilleures pratiques pour la gestion de la sécurité dans NestJS ?
Les meilleures pratiques incluent l'utilisation de HTTPS, le salage des mots de passe avec un algorithme sécurisé comme bcrypt, et la mise en œuvre de politiques d'autorisation granulaire. Il est également recommandé de régulièrement mettre à jour les dépendances et de suivre les bonnes pratiques de sécurité du code.
Comment gérer les exceptions d'authentification dans NestJS ?
Pour gérer les exceptions d'authentification, vous pouvez utiliser le décorateur `@UseGuards(AuthGuard())` sur vos contrôleurs ou méthodes. Cela permet de capturer les erreurs d'authentification et de renvoyer des réponses appropriées au client.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.