Nest G-Ressourcenauthentifizierung
Dadurch werden Sie weiter nach einer Auswahl gefragt
❯ REST-API
GraphQL (Code zuerst)
GraphQL (Schema zuerst)
Microservice (nicht HTTP)
WebSockets
Wählen Sie REST API aus. Dadurch wird das gesamte Modul mit dem DTOS-Services-Controller und dem Modul für Sie generiert
Da wir als ersten Schritt die E-Mail-/Passwort-basierte Authentifizierung implementieren, werden wir den Benutzer registrieren.
Da Nest Js eine starke Integration mit empfohlenen Validierungspaketen wie dem Klassenvalidator aufweist, verwende ich jedoch aufgrund meiner früheren Erfahrung häufig Zod für die Validierung in React-JS-Frontends und habe daher ein tolles
gefunden
Eine Lösung für das Nest-JS-Ökosystem namens Nests Zod, daher werde ich mich vorerst lieber für diese entscheiden. Um zu beginnen, installieren Sie zunächst die Bibliothek
npm i nestjs-zod
import { createZodDto } from 'nestjs-zod'; import { z } from 'zod'; const passwordStrengthRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; const registerUserSchema = z .object({ email: z.string().email(), password: z .string() .min(8) .regex( passwordStrengthRegex, 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character', ), confirmPassword: z.string().min(8), }) .refine((data) => data.password === data.confirmPassword, { message: 'Passwords do not match', }); export class RegisterUserDto extends createZodDto(registerUserSchema) {}
und wenden Sie dann die Validierungspipe auf der Route an
import { Controller, Post, Body, Version, UsePipes } from '@nestjs/common'; import { AuthService } from './auth.service'; import { RegisterUserDto } from './dto/register.dto'; import { ZodValidationPipe } from 'nestjs-zod'; @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @Version('1') @Post() @UsePipes(ZodValidationPipe) async registerUser(@Body() registerUserDto: RegisterUserDto) { return await this.authService.registerUser(registerUserDto); } }
wenn wir alle Eingaben korrekt bereitstellen
somit sind wir mit dem ersten Schritt fertig
wir haben drei Eingänge
aber wir haben explizit E-Mail hinzugefügt: z.string().email(), was für diesen Anwendungsfall ausreicht
aber um noch mehr Sicherheit zu bieten, können wir eine Desinfektionsschicht hinzufügen
import { createZodDto } from 'nestjs-zod'; import { z } from 'zod'; import * as xss from 'xss'; const passwordStrengthRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; const registerUserSchema = z .object({ email: z.string().transform((input) => xss.filterXSS(input)), // Sanitizing input using xss password: z .string() .min(8) .regex( passwordStrengthRegex, 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character', ), confirmPassword: z.string().min(8), }) .refine((data) => data.password === data.confirmPassword, { message: 'Passwords do not match', }); export class RegisterUserDto extends createZodDto(registerUserSchema) {}
Das war ein Test, den wir auch wieder hinzugefügt haben
E-Mail: z
.string()
.email()
import { createZodDto } from 'nestjs-zod'; import { z } from 'zod'; const passwordStrengthRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; const registerUserSchema = z .object({ email: z.string().email(), password: z .string() .min(8) .regex( passwordStrengthRegex, 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character', ), confirmPassword: z.string().min(8), }) .refine((data) => data.password === data.confirmPassword, { message: 'Passwords do not match', }); export class RegisterUserDto extends createZodDto(registerUserSchema) {}
Der wichtigste Punkt, den ich beachten sollte: Ich habe gerade eine Erfolgsmeldung ohne Datenbezug zurückgegeben
B. ID oder E-Mail, da in diesem Schritt keine Daten an den Benutzer zurückgesendet werden müssen. Nach der Registrierung wird der Benutzer zur Anmeldeseite weitergeleitet, um seine Daten einzugeben. Daher ist es eine gute Sicherheitsmaßnahme, das Senden unnötiger Daten zu vermeiden
Die Implementierung der Ratenbegrenzung in NestJS ist sehr einfach. Installieren Sie einfach NestJS/Throttler, konfigurieren Sie es global und fertig.
Um das Paket zu installieren, führen Sie npm i --save @nestjs/throttler
aus
import { Controller, Post, Body, Version, UsePipes } from '@nestjs/common'; import { AuthService } from './auth.service'; import { RegisterUserDto } from './dto/register.dto'; import { ZodValidationPipe } from 'nestjs-zod'; @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @Version('1') @Post() @UsePipes(ZodValidationPipe) async registerUser(@Body() registerUserDto: RegisterUserDto) { return await this.authService.registerUser(registerUserDto); } }
Dann fügen Sie NestJS Throttle Guard als globalen Guard hinzu
import { createZodDto } from 'nestjs-zod'; import { z } from 'zod'; import * as xss from 'xss'; const passwordStrengthRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/; const registerUserSchema = z .object({ email: z.string().transform((input) => xss.filterXSS(input)), // Sanitizing input using xss password: z .string() .min(8) .regex( passwordStrengthRegex, 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character', ), confirmPassword: z.string().min(8), }) .refine((data) => data.password === data.confirmPassword, { message: 'Passwords do not match', }); export class RegisterUserDto extends createZodDto(registerUserSchema) {}
und hier ist es
import { BadRequestException, Injectable, InternalServerErrorException, } from '@nestjs/common'; import { RegisterUserDto } from './dto/register.dto'; import { PrismaService } from 'src/prismaModule/prisma.service'; import * as argon2 from 'argon2'; @Injectable() export class AuthService { constructor(private readonly prismaService: PrismaService) {} async registerUser(registerUserDto: RegisterUserDto) { // data is validate and sanitized by the registerUserDto const { email, password } = registerUserDto; try { // check if user already exists const user = await this.prismaService.user.findFirst({ where: { email, }, }); if (user) { throw new BadRequestException('user already eists '); } //if use not exists lets hash user password const hashedPassword = await argon2.hash(registerUserDto.password); // time to create user const userData = await this.prismaService.user.create({ data: { email, password: hashedPassword, }, }); if (!userData) { throw new InternalServerErrorException( 'some thing went wrong while registring user', ); } // if user is created successfully then send email to user for email varification return { success: true, message: 'user created successfully', }; } catch (error) { throw error; } } }
da die Registrierung des Benutzerendpunkts ein sensibler Endpunkt-Brute-Force-Angriff ist
Andernfalls kann es zu einem Wörterbuchangriff kommen. Wir haben die Ratenbegrenzung streng gehalten
zum Senden einer Bestätigungs-E-Mail an einen Benutzer. Resend ist ein fantastischer, benutzerfreundlicher Dienst. Aber ich habe beschlossen, eine separate Episode für den gesamten Benachrichtigungsdienst zu erstellen, damit es für alle einfacher zu verstehen ist
Das obige ist der detaillierte Inhalt vonTag: Implementierung der JWT-Authentifizierung in NestJS mit Passport (Teil 1). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!