我正在尝试在 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 语句不会打印在输出上,请帮助
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
字段值。