mongodb JWT抛出错误:secretOrPrivateKey必须在nest.js中有值

cxfofazt  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(131)

auth.module.ts

import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { MongooseModule } from '@nestjs/mongoose';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { User, UserSchema } from '../user/entities/user.entity';

@Module({
  imports: [
    JwtModule.registerAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => {
        return {
          global: true,
          secret: config.get<string>('JWT_SECRET'),
          signOptions: {
            expiresIn: config.get<string | number>('JWT_EXPIRES'),
          },
        };
      },
    }),
    MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
  ],
  controllers: [AuthController],
  providers: [AuthService, JwtService],
  exports: [MongooseModule, AuthService, JwtService],
})
export class AuthModule {}

验证服务.ts

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User } from '../user/entities/user.entity';

import { JwtService } from '@nestjs/jwt';
import { LoginDto } from './dto/login.dto';

@Injectable()
export class AuthService {
  constructor(
    @InjectModel(User.name)
    private userModel: Model<User>,
    private jwtService: JwtService,
  ) {}

  async login(loginDto: LoginDto): Promise<{ token: string }> {
    const { username, password } = loginDto;

    const user = await this.userModel.findOne({ username });

    if (!user) {
      throw new UnauthorizedException('Invalid email or password');
    }
    if (user.password !== password) {
      throw new UnauthorizedException('Invalid email or password');
    }
    const token = await this.jwtService.signAsync({ id: user._id });

    return { token };
  }
}

auth.guard.ts

import {
  CanActivate,
  ExecutionContext,
  Injectable,
  UnauthorizedException,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { InjectModel } from '@nestjs/mongoose';
import { Request } from 'express';
import { Model } from 'mongoose';
import { User } from '../user/entities/user.entity';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    @InjectModel(User.name)
    private userModel: Model<User>,
    private jwtService: JwtService,
    private readonly configService: ConfigService,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const token = this.extractTokenFromHeader(request);
    if (!token) {
      throw new UnauthorizedException(
        'You are not authorized to access this resource.',
      );
    }
    try {
      const payload = await this.jwtService.verifyAsync(token, {
        secret: this.configService.get<string>('JWT_SECRET'),
      });
      console.log('payload ->>', payload);
      const user = await this.userModel.findById(payload.id);

      if (!user) {
        throw new UnauthorizedException('User not found.');
      }
      request['user'] = user;
    } catch {
      throw new UnauthorizedException(
        'You are not authorized to access this resource.',
      );
    }
    return true;
  }

  private extractTokenFromHeader(request: Request): string | undefined {
    const [type, token] = request.headers.authorization?.split(' ') ?? [];
    return type === 'Bearer' ? token : undefined;
  }
}

当我调用登录API时,
错误:secretOrPrivateKey必须具有值
我在stackoverflow上找到了一些答案。它说从auth.module.ts中的提供程序中删除JwtService
我也试过这个,但它给予我另一个错误
Nest无法解析AuthGuard(UserModel,?、ConfigService)。请确保索引[1]处的JwtService参数在BookModule上下文中可用。
我不知道我错过了什么
Thanks in advance
快乐编码!

toiithl6

toiithl61#

可能是你没有定义你的env变量或者ConfigModule设置错误。根据the official NestJs documentation,您必须在AppModule导入中包含ConfigModule.forRoot()。为了处理各种env文件(例如.development.env),必须像这样指定它们的路径:

ConfigModule.forRoot({
  envFilePath: '.development.env',
});

同样,最后但并非最不重要的是,检查你的环境文件中的拼写错误。它应该包含JWT_SECRET的值。虽然这与最初的问题无关,但考虑使用像zod这样的库来验证您的.env文件,以避免拼写错误或繁琐的env调试。

相关问题