В областта на уеб разработката сигурността е от изключително значение. Като разработчици, ние трябва да гарантираме, че нашите приложения са защитени срещу неоторизиран достъп и че чувствителните данни остават защитени. NestJS, мощна Node.js рамка, прави внедряването на надеждни механизми за удостоверяване и оторизация лесно. В това изчерпателно ръководство, пригодено за начинаещи в NestJS, ще проучим концепциите за удостоверяване и оторизация и техните разлики и ще предоставим практически реализации с помощта на популярни стратегии. Така че, закопчайте коланите и се пригответе да овладеете изкуството на сигурното управление на потребителите!

Разбиране на автентификацията и оторизацията

Преди да се потопим в техническите подробности, нека разберем фундаменталната разлика между удостоверяване и оторизация:

  1. Удостоверяване: Удостоверяването е процес на потвърждаване на самоличността на потребител, който се опитва да получи достъп до нашето приложение. Той отговаря на въпроса „Кой си ти?“ и гарантира, че потребителят е истински. Веднъж удостоверен, потребителят получава достъп до защитени ресурси.
  2. Упълномощаване: Упълномощаването, от друга страна, идва след удостоверяване. Той определя до какви действия или ресурси има достъп даден потребител въз основа на тяхната самоличност и роли. Упълномощаването отговаря на въпроса „Какво имате право да правите?“

Настройване на удостоверяване в NestJS

За да започнем пътуването си в сферата на удостоверяването, ще използваме популярния пакет passport — добре познат междинен софтуер за приложения Node.js. Той предлага широк набор от стратегии за удостоверяване, включително Local, OAuth и JWT (JSON Web Tokens).

Стъпка 1: Инсталиране на зависимости

Нека започнем с инсталирането на необходимите пакети за удостоверяване:

npm install @nestjs/passport passport passport-local
npm install @nestjs/jwt passport-jwt

Стъпка 2: Създайте местна стратегия

За нашия първи пример ще приложим проста локална стратегия, която удостоверява потребителите с помощта на комбинация от потребителско име и парола. Първо, нека създадем нова папка с име auth в корена на вашия NestJS проект. В тази папка създайте нов файл с име local.strategy.ts.

// auth/local.strategy.ts
import { Injectable } from '@nestjs/common';
import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { AuthService } from './auth.service';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {

  constructor(private readonly authService: AuthService) {
    super({ usernameField: 'email' }); // Replace 'email' with the actual field used for the username
  }

  async validate(username: string, password: string): Promise<any> {
    const user = await this.authService.validateUser(username, password);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

В кода по-горе ние дефинираме нашия LocalStrategy клас, който разширява PassportStrategy. Предоставяме и името на полето, използвано за потребителското име (в този случай email). Методът validate се извиква, когато потребител се опита да влезе. Вътре в този метод ние извикваме метода validateUser на нашия AuthService, който ще внедрим скоро.

Стъпка 3: Внедрете услугата за удостоверяване

Сега, след като имаме нашия LocalStrategy, нека внедрим AuthService, който ще обработва потребителското валидиране:

// auth/auth.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class AuthService {

   // Replace this dummy data with actual user data from a database or external service
   private readonly users = [
   {
     userId: 1,
     email: '[email protected]',
     password: 'strongPassword',
   },
   {
     userId: 2,
     email: '[email protected]',
     password: 'password123',
     },
   ];

  async validateUser(username: string, password: string): Promise<any> {
     const user = this.users.find(
     (user) => user.email === username && user.password === password,
     );
    return user;
   }
}

В този пример имаме прост масив users, съдържащ фиктивни потребителски данни. В приложение от реалния свят бихте извличали потребителски данни от база данни или външна услуга. Методът validateUser сравнява предоставените потребителско име и парола с потребителските данни и връща потребителския обект, ако идентификационните данни са валидни.

Стъпка 4: Внедрете модула за удостоверяване

Сега, след като имаме нашите LocalStrategy и AuthService, нека създадем модула Auth, за да свържем всичко заедно:

// auth/auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { LocalStrategy } from './local.strategy';
import { PassportModule } from '@nestjs/passport';

@Module({
   imports: [PassportModule],
   providers: [AuthService, LocalStrategy],
})
export class AuthModule {}

В този модул импортираме PassportModule, което е необходимо за използване на PassportStrategy класове. След това предоставяме AuthService и LocalStrategy като доставчици, за да ги направим достъпни в нашето приложение.

Стъпка 5: Добавяне на удостоверяване към главния модул

И накрая, нека добавим AuthModule към нашия основен приложен модул:

// app.module.ts
import { Module } from '@nestjs/common';
import { AuthModule } from './auth/auth.module';
@Module({
 imports: [AuthModule],
 controllers: [],
 providers: [],
})
export class AppModule {}

Като добавим AuthModule към основния ни модул, ние активираме удостоверяване за цялото ни приложение.

Практичен и забавен пример за код: Защита на маршрути

Сега, след като настроихме удостоверяване, нека приложим практически пример, като защитим конкретен маршрут в нашето приложение. Да предположим, че имаме крайна точка за строго секретна рецепта, която искаме да разкрием само на оторизирани потребители. Ето как можем да постигнем това:

// recipes.controller.ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Controller('recipes')
export class RecipesController {

  @Get('top-secret')
  @UseGuards(AuthGuard('jwt'))
  getTopSecretRecipe(): string {
    return 'Shhh! The top-secret recipe is…';
  }
}

В този пример използваме AuthGuard от @nestjs/passport, за да защитим маршрута getTopSecretRecipe. Това означава, че само удостоверени потребители с валиден JWT (JSON Web Token) ще имат достъп до строго секретната рецепта.

Заключение

Честито! Успешно внедрихте удостоверяване и оторизация във вашето приложение NestJS. Научихте разликата между удостоверяване и оторизация, настроихте пакета passport за потребителско валидиране и защитените маршрути с помощта на AuthGuard. С това новооткрито знание вече можете да създавате защитени уеб приложения с лекота.

Не забравяйте, че сигурността е пътуване, а не дестинация. Докато продължавате своето пътуване в разработката, продължавайте да изследвате най-добрите практики и бъдете в крак с най-новите подобрения в сигурността. Създаването на защитени приложения е едновременно предизвикателство и възнаграждаващо изживяване и с NestJS като ваш спътник вие сте добре подготвени да се изправите пред всякакви предизвикателства при удостоверяване и оторизация, които се изправят пред вас.

Така че, давайте напред и създавайте невероятни, сигурни приложения с NestJS!