LocalAuthGuard不能在带有typeorm和Passport-local的nestjs应用程序中工作 [英] LocalAuthGuard not working in nestjs app with typeorm and passport-local

查看:16
本文介绍了LocalAuthGuard不能在带有typeorm和Passport-local的nestjs应用程序中工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有typeorm、Passport-JWT和Passport-local的nestjs8.0。除了LocalAuthGuard之外,其他一切似乎都运行得很好。我可以成功创建新用户,甚至可以使用具有JwtAuthGuard的路由,但LocalAuthGuard似乎有一些问题,因为我不断收到401未经授权的错误

另外,是否有办法通过控制台记录LocalAuthGuard或LocalStrategy中的某些输出?

auth.Controler.ts

@Controller(['admin', 'user'])
export class AuthController {
  constructor(
    private authService: AuthService,
  ) {}

  @UseGuards(LocalAuthGuard)
  @Post('login')
  login(@Request() req) {
    console.log('object');
    if (req.path.includes('admin') && !req.user.isAdmin) {
      throw new UnauthorizedException();
    }
    return this.authService.login(req.user);
  }

...
}

local.Guard.ts

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

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

local.Strategy y.ts

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

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

auth.service.ts

@Injectable()
export class AuthService {
  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    private jwtService: JwtService,
  ) {}

  async validateUser({ usernameOrEmail, password }: LoginDto) {
    const user = (await this.userRepository.findOne({ username: usernameOrEmail })) ||
  (await this.userRepository.findOne({ email: usernameOrEmail }));
    if (user && (await bcrypt.compare(password, user.password))) {
      return user;
    }

    return null;
  }
...
}

auth.module e.ts

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    PassportModule,
    JwtModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => {
        return {
          secret: configService.get('JWT_KEY'),
          signOptions: {
            expiresIn: '6000s',
          },
        };
      },
    }),
  ],
  providers: [AuthService, LocalStrategy, JwtStrategy],
  exports: [AuthService],
  controllers: [AuthController],
})
export class AuthModule {}

我们非常感谢您的任何帮助或建议。

编辑

似乎对于LocalAuthGuard,用户名和密码是必须的,其他属性是可选的。

推荐答案

您可以使用不同的参数创建多个本地策略。例如,

  1. 用户名和密码
  2. 电话和OTP
  3. 电子邮件和密码
  4. 电子邮件和动态口令

使用多个本地策略refer to this answer

然后,您还可以传递Options对象来指定不同的属性名称,例如:super({ usernameField: 'email', passwordField: 'otp' })

按如下方式实施本地化战略

import { Strategy } from 'passport-local';
import { PassportStrategy } from '@nestjs/passport';
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { IAuthService } from '../services';
import { LoginDto, OtpLoginDto } from '../dto';
import { UserDto } from 'src/modules/user/dto';
import { plainToClass } from 'class-transformer';

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(
    @Inject(IAuthService)
    private readonly authService: IAuthService,
  ) {
    super({
      usernameField: 'user_name',
      passwordField: 'otp',
    });
  }

  async validate(user_name: string, otp: string): Promise<any> {
    const loginDto = plainToClass(OtpLoginDto, {
      username: user_name,
      otp: otp,
    });
    const user: UserDto = await this.authService.verifyOtp(loginDto);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

引用:customize passport

这篇关于LocalAuthGuard不能在带有typeorm和Passport-local的nestjs应用程序中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆