在 Nest .js 中使用 authguard 时出现持续未经授权的消息响应

问题描述 投票:0回答:1

我正在尝试在 Nest js 中使用 authguard,但我不断收到此未经授权的错误,让我在这里分享所有代码

//auth service
import { Injectable, UseFilters } from '@nestjs/common';
import { CreateAuthDto } from './dto/create-auth.dto';
import { UpdateAuthDto } from './dto/update-auth.dto';
import { InjectModel } from '@nestjs/mongoose';
import { AuthDocument ,Auth } from './Schema/userAuth';
import { Model } from 'mongoose';
import { JwtService } from '@nestjs/jwt';
@Injectable()
export class AuthService {
  constructor(@InjectModel(Auth.name) private AuthModel:Model<AuthDocument> ,private JwtService :JwtService){

  };


  create(createAuthDto: CreateAuthDto):Promise<Auth> {
    console.log(createAuthDto);
   const user=  new this.AuthModel;
   user.Name= createAuthDto.Name;
   user.Username= createAuthDto.Username;
   user.Email = createAuthDto.Email;
   user.Password = createAuthDto.Password;
    return user.save();
  }
  
  async login(Username: string, Password: string): Promise<any> {

    try {
      const user = await this.AuthModel.findOne({ Username:Username }).exec();
      if(!user){
        return 'user not found' ;
      }
      if(user.Password == Password){
      
      
        const payload = { Username ,Password} ;
    const accessToken = this.JwtService.sign(payload)
     console.log(payload);
     console.log(accessToken);
       
        return {accessToken};
      }
    } catch (error) {
      console.error('Error finding user:', error);
      return 'Error finding user';
    }
  }
  findAll() {
    return `This action returns all auth`;
  }

  findOne(Email:string) :Promise<Auth> {
    const user = this.AuthModel.findOne({Email:Email})
    return user;
  }

  update(id: number, updateAuthDto: UpdateAuthDto) {
    return `This action updates a #${id} auth`;
  }

  remove(id: number) {
    return `This action removes a #${id} auth`;
  }
}

//auth module
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { MongooseModule } from '@nestjs/mongoose';
import { userSchema ,Auth} from './Schema/userAuth';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { LocalStrategy } from './strategies/local.strategy';
import { LocalGuard } from './guards/local.guard';

@Module({
  imports:[MongooseModule.forFeature([{name:Auth.name,schema:userSchema}]) ,
  JwtModule.register({
    secret:"H@rsh123",
    signOptions:{
      expiresIn:"1h"
    }
  }),PassportModule],
  controllers: [AuthController ],
  providers: [AuthService ,LocalStrategy ,LocalGuard],
})
export class AuthModule {}

//auth control
import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards } from '@nestjs/common';
import { AuthService } from './auth.service';
import { CreateAuthDto } from './dto/create-auth.dto';
import { UpdateAuthDto } from './dto/update-auth.dto';
import { AuthGuard } from '@nestjs/passport';
import { LocalGuard } from './guards/local.guard';
import { LocalStrategy } from './strategies/local.strategy';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @Post('signup')
  create(@Body() createAuthDto: CreateAuthDto) {
    return this.authService.create(createAuthDto);
  }
  @Post('login')
  @UseGuards(LocalGuard)
  async login(@Body() requestBody:{Username:string ,Password :string}){
    const {Username , Password} = requestBody;
    const user= await this.authService.login(Username , Password);
    
    if(!user){
      return 'invalid user';
    }
    return user;
  }
  @Get()
  findAll() {
    return this.authService.findAll();
  }

  @Get(':Username')
  findOne(@Param('Username') Username: string) {
    return this.authService.findOne(Username);
  }

  @Patch(':id')
  update(@Param('id') id: string, @Body() updateAuthDto: UpdateAuthDto) {
    return this.authService.update(+id, updateAuthDto);
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.authService.remove(+id);
  }
}

//local-strategy
// local.strategy.ts
import { Strategy } from 'passport-local';
import { 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(payLoad :any): Promise<any> {
    const {username,password} = payLoad;
    console.log('user', username, password);
    const user = await this.authService.login(username, password);

    if (!user) {
      throw new UnauthorizedException();
    }

    return user;
  }
}

//localguard
import { ExecutionContext, Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { Observable } from "rxjs";

@Injectable()

export class LocalGuard extends AuthGuard('local'){
    canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
        console.log('hello');
        return super.canActivate(context);
    }
}

如果我删除 @UseGuards() ,一切都会正常工作,但是当我使用它时,它总是会给出 401 代码的未经授权的错误,甚至不会调用验证函数,因为 console.log 语句不会打印在输出上,请帮助

node.js jwt nestjs passport.js passport-local
1个回答
0
投票

Passport 希望您发送

username
password
作为请求正文的字段。如果您想使用其他内容,例如
Username
,而且大小写也很重要,那么您需要将这一更改告知 Passport。您可以通过将选项传递给
super
构造函数的
LocalStrategy
方法来实现此目的,例如

import { Strategy } from 'passport-local';
import { 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({
      usernameField: 'Username',
      passwordField: 'Password',
    });
  }

  async validate(username :string, password: string): Promise<any> {
    console.log('user', username, password);
    const user = await this.authService.login(username, password);

    if (!user) {
      throw new UnauthorizedException();
    }

    return user;
  }
}

另请注意,

validate
方法有两个参数:
username
字段值和
password
字段值。

© www.soinside.com 2019 - 2024. All rights reserved.