我正在尝试实施 Passport 本地策略,但验证方法不起作用。当我执行
@UseGuards(AuthGuard("local"))
时,它会自动抛出未经授权的异常,而无需通过我编写的验证方法。我不知道我做错了什么,因为文档也是如此。
这是我的 LocalStrategy 课程:
@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
constructor(
@InjectRepository(UserRepository) private userRepository: UserRepository,
) {
super();
}
async validate(credentials: string, password: string): Promise<User> {
// this method is never called, I've already did some console.logs
const user = await this.userRepository.findByCredentials(credentials);
if (!user) throw new UnauthorizedException('Invalid credentials');
if (!(await argon2.verify(user.hash, password)))
throw new UnauthorizedException('Invalid credentials');
return user;
}
}
我的AuthModule导入:
@Module({
imports: [TypeOrmModule.forFeature([UserRepository]), PassportModule],
controllers: [AuthController],
providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
使用示例:
@Post("/login")
@UseGuards(LocalAuthGuard)
async login(@Body() loginDto: LoginDto) {
return this.authService.login(loginDto);
}
在花了更多时间研究代码并自己深入研究之后,validate
方法必须具有参数
named
username
和password
,这并不是事实,它们可以是bob
和alice
对于所有这些都很重要,但是 重要的是你的
req.body
有两个属性 username
和 password
。如果您没有 req.body.username
和 req.body.password
,那么您将永远无法进入 validate
班的 LocalStrategy
。
validate
方法
must具有参数
username
和password
或参数must与传递给构造函数中
usernameField
的passwordField
和super()
值相匹配。如果它们不匹配,则不会调用 validate
方法。我认为这是因为 Nest 调用了 validate(...args)
,但我不能 100% 确定。
async validate(payload: {email: string, UserId: number, role: string}) {
return { userId: payload.UserId, email:payload.email, role:payload.role };
}
我这样签署令牌:
async signToken(userId: number, email: string, role: string): Promise<{access_token:string}>{
const payload = {
UserId: userId,
email: email,
role: role
}
console.log(payload)
const secret = process.env.JWT_SECRET
const token = await this.JwtService.signAsync(payload, {
expiresIn: "1d",
secret: secret
})
LocalAuthGuard
课程。您需要使用此类创建一个文件,然后..
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class LocalAuthGuard extends AuthGuard('local') {}
然后将使用当地警卫。