Les décorateurs et les middlewares sont le pain et le beurre de NestJS : des outils qui peuvent vous rendre la vie soit incroyablement facile, soit légèrement écrasante, selon la façon dont vous les abordez.
Aujourd'hui, passons en revue la création d'un décorateur et d'un middleware personnalisés pour l'authentification des utilisateurs, tout en gardant les choses légères et simples. Prenez votre café et plongeons-y !
Tout d’abord, définissons une interface pour notre objet utilisateur.
Cela garantira la sécurité des types et gardera notre IDE heureux (et qui n'aime pas un IDE heureux ?).
export interface IUser { id: string; name: string; primaryEmail: string; phoneNumber: string | null; countryCode: string | null; dob: Date | null; createdAt: Date; updatedAt?: Date; deletedAt?: Date | null; }
Les décorateurs personnalisés sont comme les enfants cool d'une application NestJS.
Ici, nous en créons un pour récupérer les métadonnées utilisateur de l'objet de requête.
import { createParamDecorator, ExecutionContext } from '@nestjs/common'; import { IUser } from '../interface/user.interface'; export const UserMetadata = createParamDecorator( (_data: unknown, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); return request.user as IUser; }, );
C'est ça ! Ce décorateur peut désormais être utilisé pour extraire les informations utilisateur directement dans les méthodes de votre contrôleur.
Maintenant, créons un AuthGuard pour protéger nos points de terminaison comme un videur virtuel.
import { CanActivate, ExecutionContext, ForbiddenException, Injectable } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { verify } from 'jsonwebtoken'; import { Observable } from 'rxjs'; import { IS_PUBLIC_KEY } from '../constant/core'; import { IUser } from '../interface/user.interface'; @Injectable() export class AuthGuard implements CanActivate { constructor( private reflector: Reflector, ) { } canActivate( context: ExecutionContext, ): boolean | Promise<boolean> | Observable<boolean> { const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [ context.getHandler(), context.getClass(), ]); if (isPublic) { return true; } const request = context.switchToHttp().getRequest(); const headers = request.headers; const token = (headers['authorization'] || '').split(' ')[1]; if (!token) { throw new ForbiddenException('Not Authenticated'); } const jwtOpts = { expiresIn: '1h', // Replace with env vars in real use audience: 'your-audience', algorithm: 'HS256', issuer: 'your-issuer', }; try { const decoded = verify(token, "my-jwt-secret-token", { audience: jwtOpts.audience, issuer: jwtOpts.issuer, }) as { user: IUser }; request.user = decoded.user; return true; } catch (err) { throw new ForbiddenException('Session Expired or Invalid'); } } }
Certaines routes doivent être publiques (comme la connexion), et d'autres peuvent être internes.
Ajoutons pour cela deux décorateurs simples.
import { SetMetadata } from '@nestjs/common'; export const IS_PUBLIC_KEY = 'isPublic'; export const IS_INTERNAL = 'isInternal'; export const Public = () => SetMetadata(IS_PUBLIC_KEY, true); export const Internal = () => SetMetadata(IS_INTERNAL, true);
Enfin, voici comment utiliser tout cela dans votre contrôleur.
import { Controller, Get, UseGuards } from '@nestjs/common'; import { UserMetadata } from '../decorators/user.decorator'; import { AuthGuard } from '../guards/auth.guard'; import { Public } from '../decorators/public.decorator'; @Controller('users') export class UserController { @Public() @Get('login') login() { return { message: 'Login endpoint (public)' }; } @UseGuards(AuthGuard) @Get('profile') getProfile(@UserMetadata() user: IUser) { return { message: 'User Profile', user, }; } }
Et voilà ! Vous avez créé un décorateur personnalisé, un middleware et des décorateurs de métadonnées pour gérer les itinéraires publics.
En utilisant ces outils, vous pouvez créer des API sécurisées et organisées dans NestJS.
Si cela vous semble trop difficile, n'oubliez pas : même Rome n'a pas été construite en un jour, mais vos API peuvent certainement évoluer plus rapidement !
N'hésitez pas à modifier et expérimenter ces extraits.
Il n’y a aucune limite avec NestJS ! ?
Je travaille sur un outil très pratique appelé LiveAPI.
Il est conçu pour faciliter la documentation des API pour les développeurs.
Avec LiveAPI, vous pouvez générer rapidement une documentation interactive sur les API qui permet aux utilisateurs d'exécuter des API directement depuis le navigateur.
Si vous en avez assez de créer manuellement des documents pour vos API, cet outil pourrait bien vous faciliter la vie.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!