我使用以下方法:
定义架构时,将静态方法添加到 Mongoose 架构:
UserSchema.methods.comparePassword = async function(candidatePassword: string) {
return await bcrypt.compare(candidatePassword, this.password);
};
还要在对象的接口定义中包含该方法:
export interface User {
firstName: string;
...
comparePassword(candidatePassword: string): Promise<boolean>;
}
以及 UserDocument 界面
export interface UserDocument extends User, Document { }
所以现在我的用户服务:
export class UsersService {
constructor(@InjectModel(Schemas.User) private readonly userRepository: Model<UserDocument>,
private readonly walletService: WalletsService,
@Inject(Modules.Logger) private readonly logger: Logger) {}
async findByEmail(email: string): Promise<UserDocument> {
return await this.userRepository.findOne({ email }).select('password');
}
...
}
为了将这一切联系在一起,当用户尝试登录时,Auth 服务通过 id 检索用户对象,并调用该用户对象的 comparePassword 实例方法:
@Injectable()
export class AuthService {
constructor(
private readonly usersService: UsersService,
private readonly jwtService: JwtService,
) { }
async signIn({ email, password }: SignInDto): Promise<LoginResponse> {
const user = await this.usersService.findByEmail(email);
if (!user) { throw new UnauthorizedException('Invalid Username or Password'); }
if (await user.comparePassword(password)) {
const tokenPayload: JwtPayload = { userId: user.id };
const token = this.jwtService.sign(tokenPayload);
return ({ token, userId: user.id, status: LoginStatus.success });
} else {
throw new UnauthorizedException('Invalid Username or Password');
}
}
}