javascript - NestJS JWT მოდულის პრობლემები
მქონდა პრობლემები JWTModule-თან NestJS-ში. მუდმივად ვიღებ ამ შეცდომას, მაშინაც კი, როცა საიდუმლოს პირდაპირ კონფიგურაციაში ვაწვდი, ჩემს env ფაილიდან არა. ვერ ვხსნი, რასაც ვიღაც მორიგება.
Error: secretOrPrivateKey must have a value
მოკლე მიმოხილვა, როგორ იმოქმედებს ეს.
- კლიენტი გამოიძახებს /auth/login { username: string, password: string }
- LocalStrategy დაცვის მექანიზმი მოუწევს AuthService-ის validateUser მეთოდს, რომელიც მოუწევს ldapServices-ის authenticateUser მეთოდს და აბრუნებს მომხმარებელს.
- იმ ადგილიდან მე უნდა მივიღო მომხმარებლის მონაცემები LDAP-დან და შევაერთო ისინი იმ მონაცემებთან, რაც გვაქვს ჩვენს Mongo DB-ში. ეს ყველაფერი კარგად მუშაობს.
- როდესაც დაცვის გარდა გავლის შემდეგ, ის გამოიძახებს 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-სთვის.