Доступ до локального зберігання в NestJS

Приклад сервісу для ідентифікації користувачів

Коли ви створюєте систему, що вимагає ідентифікації користувачів у внутрішній функції, розгляньте наступний приклад сервісу (за умови, що модуль ресурсу вже створено):

import { Injectable } from '@nestjs/common';  
import { Repository } from 'typeorm';  
import { InjectRepository } from '@nestjs/typeorm';  
import { User } from './user.entity';
@Injectable()  
export class UserService {  
 constructor(  
 @InjectRepository(User)  
 private readonly userRepository: Repository,  
 ) {}  
 async getUser(userId: string) {  
 return this.userRepository.findOne({ where: { id: userId } }); // Знайти одного користувача.  
 }  
}

Додавання аутентифікації

Тепер уявімо, що вам потрібно аутентифікувати внутрішній сервіс для перевірки чогось за допомогою bearerToken, що передається в заголовку запиту. Зазвичай для цього використовують токен як параметр:

import { Injectable } from '@nestjs/common';  
import { Repository } from 'typeorm';  
import { InjectRepository } from '@nestjs/typeorm';  
import { User } from './user.entity';
@Injectable()  
export class UserService {  
 constructor(  
 @InjectRepository(User)  
 private readonly userRepository: Repository,  
 ) {}  
 async getUser(userId: string, bearerToken: string) {  
 const user = await this.userRepository.findOne({ where: { id: userId } });  
 const isValid = someFunc(bearerToken); // Перевірка токена.  
 return { user, isValid };  
 }  
}

Однак передача bearerToken як параметра може бути не завжди ідеальною, оскільки це не безпосередньо пов'язано з логікою getUser.

Рішення за допомогою AsyncLocalStorage

Замість того, щоб передавати токен як параметр, ви можете зберігати його за допомогою AsyncLocalStorage, що надається NestJS, і отримувати його в будь-якому місці вашого коду. Пакет nestjs-cls спрощує цей процес.

Налаштування nestjs-cls

Встановіть пакет:

npm install nestjs-cls

Потім налаштуйте його в AppModule, щоб увімкнути ClsMiddleware глобально:

import { Module } from '@nestjs/common';  
import { ClsModule } from 'nestjs-cls';  
import { UserService } from './user.service';  
import { UserController } from './user.controller';
@Module({  
 imports: [  
 ClsModule.forRoot({  
 middleware: {  
 // Автоматичне підключення middleware для всіх маршрутів  
 mount: true,  
 setup: (cls, req) => {  
 // Зберігайте токен аутентифікації з заголовка в AsyncLocalStorage  
 cls.set('userToken', req.headers['x-user-token']);  
 },  
 },  
 }),  
 ],  
 providers: [UserService],  
 controllers: [UserController],  
})  
export class AppModule {}

Використання ClsService в Сервісі

Тепер ви можете безпосередньо отримати доступ до AsyncLocalStorage у UserService:

import { Injectable } from '@nestjs/common';  
import { Repository } from 'typeorm';  
import { InjectRepository } from '@nestjs/typeorm';  
import { ClsService } from 'nestjs-cls';  
import { User } from './user.entity';
@Injectable()  
export class UserService {  
 constructor(  
 @InjectRepository(User)  
 private readonly userRepository: Repository,  
 private readonly cls: ClsService, // Впроваджуємо ClsService  
 ) {}  
 async getUser(userId: string) {  
 const user = await this.userRepository.findOne({ where: { id: userId } });  
 // Отримуємо токен, збережений в AsyncLocalStorage  
 const bearerToken = this.cls.get('userToken');  
 const isValid = someFunc(bearerToken); // Перевіряємо токен  
 return { user, isValid };  
 }  
}

Переваги nestjs-cls

  • Уникає передачі зайвих параметрів: Отримуйте доступ до контекстних даних, таких як токени, в будь-якому місці виконання.
  • Легкість налаштування: Middleware автоматично обробляє конфігурацію.
  • Безшовна інтеграція з NestJS: Спрощує реалізацію за допомогою вбудованих інструментів фреймворку.

Посилання

офіційна документація AsyncLocalStorage для NestJS

Перекладено з: Accessing Local Storage in NestJS

Leave a Reply

Your email address will not be published. Required fields are marked *