javascript - NestJS JWT მოდულის პრობლემები


მქონდა პრობლემები JWTModule-თან NestJS-ში. მუდმივად ვიღებ ამ შეცდომას, მაშინაც კი, როცა საიდუმლოს პირდაპირ კონფიგურაციაში ვაწვდი, ჩემს env ფაილიდან არა. ვერ ვხსნი, რასაც ვიღაც მორიგება.

Error: secretOrPrivateKey must have a value

მოკლე მიმოხილვა, როგორ იმოქმედებს ეს.

  1. კლიენტი გამოიძახებს /auth/login { username: string, password: string }
  2. LocalStrategy დაცვის მექანიზმი მოუწევს AuthService-ის validateUser მეთოდს, რომელიც მოუწევს ldapServices-ის authenticateUser მეთოდს და აბრუნებს მომხმარებელს.
  3. იმ ადგილიდან მე უნდა მივიღო მომხმარებლის მონაცემები LDAP-დან და შევაერთო ისინი იმ მონაცემებთან, რაც გვაქვს ჩვენს Mongo DB-ში. ეს ყველაფერი კარგად მუშაობს.
  4. როდესაც დაცვის გარდა გავლის შემდეგ, ის გამოიძახებს AuthService-ის login მეთოდს. რომელიც უნდა შექმნას და დადასტუროს payload JWT-ით, გამოყენებით JwtService-ს (რომელიც მოწოდებულია NestJS-ით). აქ ხდება ჩემი პრობლემა.

აქაა ფაილები და მათი კოდი:

აპპი.კონტროლერი.ts

import { Controller, Get, Post, Request, UseGuards } from '@nestjs/common';
import { AppService } from './app.service';
import { AuthService } from './providers/auth/auth.service';
import { LocalAuthGuard } from './providers/auth/local.strategy';

@Controller()
export class AppController {
  constructor(private readonly authService: AuthService) {}

  @UseGuards(LocalAuthGuard)
  @Post('/auth/login')
  async login(@Request() req) {
    return this.authService.login(req.user);
  }
}

auth.module.ts

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UserModule } from './../../endpoints/user/user.module';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './local.strategy';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { UserService } from './../../endpoints/user/user.service';
import { LdapService } from './../ldap/ldap-service';
import { jwtConstants } from './constants';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [
    UserModule,
    PassportModule,
    JwtModule.register({
      secret: '2I*5f5OE9tlGIbg*3Q*C',
      signOptions: { expiresIn: '12h' },
    }),
  ],
  providers: [AuthService, LocalStrategy, LdapService],
  controllers: [AuthController],
  exports: [AuthService],
})
export class AuthModule {}

auth.service.ts

import { Injectable } from '@nestjs/common';
import { LdapService } from '../ldap/ldap-service';
import { UserService } from './../../endpoints/user/user.service';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
  constructor(
    private readonly ldapService: LdapService,
    private readonly userService: UserService,
    private readonly jwtService: JwtService
  ) {}

  async validateUser(username: string, pass: string): Promise<any> {
    const authenticated = await this.ldapService.authenticateUser(
      username,
      pass,
    );

    if (authenticated === true) {
      console.log(authenticated, username, pass)
      return await this.userService.getUserById(username);
    }
    return null;
  }

  async login(user: any) {
    const payload = { ...user, sub: user.accountName };
    console.log(process.env.JWT_SECRET, payload);
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}

ადგილობრივი.სტრატეგია.ts

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

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private authService: AuthService) {
    super();
  }

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

@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}

ვრწმუნობ, რაღაც პატარა მრჩება. ვაფასებ დახმარებას.

პასუხი #1

კომენტარებში განხილების შემდეგ აღმოჩნდა, რომ AuthService აღდგებოდა, როგორც შედეგი იმისა, რომ მას ერთხელ უფრო მეტს ახლებულად დაამატებდნენ providers მასივში. რადგან JwtService აქვს @Optional() პარამეტრები, რომელიც შეიძლება მიაწოდოს, მისი დუბლირება შეცდომას არ გამოიწვევდა, მაგრამ მას არ მიეცემოდა იგივე პარამეტრები, რაც JwtModule.register განსაზღვრავს. ეს გამოსასწორებლად, AuthModule აკეთებს exports: [AuthService] და ნებისმიერი მოდული, რომელსაც სჭირდება AuthService, დაამატებს imports: [AuthModule], რათა მხოლოდ ერთი AuthService შეიქმნას და მას მიეწოდოს სწორი JwtService პარამეტრები JwtModule-სთვის.