我的 authservice.ts 文件如下:
import { Injectable, UnauthorizedException } from '@nestjs/common';
import { UsersService } from '../users/users.service';
import { JwtService } from '@nestjs/jwt';
import { LoginUserDto } from 'src/users/dto/loginUser.dto';
import { JwtPayload } from './interfaces/jwt-payload.interface';
@Injectable()
export class AuthService {
constructor(
private usersService: UsersService,
private jwtService: JwtService,
) {}
async validateUserByPassword(loginAttempt: LoginUserDto) {
// This will be need used for the initial login
let userToAttempt = await this.usersService.findOneByEmail(loginAttempt.email);
return new Promise((resolve) => {
// Check the supplied password against the hash stored for this email address
userToAttempt.checkPassword(loginAttempt.password, (err, isMatch) => {
if (err) throw new UnauthorizedException();
if (isMatch) {
// If there is a successful match, generate a JWT for the user
resolve(this.createJwtPayload(userToAttempt));
} else {
throw new UnauthorizedException();
}
});
});
}
async validateUserbyJwt(payload: JwtPayload) {
//This will be used when the user has already logged in and has a JWT
let user = await this.usersService.findOneByEmail(payload.email);
if (user) {
return this.createJwtPayload(user);
} else {
throw new UnauthorizedException();
}
}
createJwtload(user) {
let data: JwtPayload = {
email: user.mail
};
let jwt = this.jwtService.sign(data);
return {
expiresIn: 3600,
token: jwt
}
}
}
当用户最初使用电子邮件和密码登录时,将使用validateUserByPassword方法。此方法在MongoDB中找到与提供的电子邮件匹配的用户,然后它将调用添加到User模式的自定义checkPassword方法。
schemas.users.ts
import * as mongoose from 'mongoose';
import * as bcrypt from 'bcrypt';
export interface IUser extends mongoose.Document {
username: string,
password:string
}
export const UserSchema = new mongoose.Schema({
firstname: {
type: String,
required: [true, 'Please, Enter your Name'],
},
lastname: {
type: String,
required: [true, 'Please, Enter your Lastname'],
},
password: {
type: String,
required: [true, 'Please Enter your Password'],
},
email: {
type: String,
unique:true,
required: [true, 'Please Enter your Email'],
},
phone: {
type: String,
optional: true
},
address: {
type: String,
optional: true,
},
datecreated: {
type: Date,
default: Date.now }
});
UserSchema.pre<IUser>('save', function(next) {
const user = this;
//Make sure not to rehash the password if it is already rehashed
if(!user.isModified('password')) {
return next();
}
//Generate a salt and use it to hash the user's password
bcrypt.genSalt(10, (err, salt) => {
if (err) {
return next(err);
}
bcrypt.hash(user.password, salt, (err: mongoose.Error, hash) => {
if (err) {
return next(err);
}
user.password = hash;
next();
});
});
});
UserSchema.methods.checkpassword = function(attempt, callback){
const user = this;
bcrypt.compare(attempt, user.password, (err, isMatch) => {
if(err) return callback(err);
callback(null, isMatch);
});
};
如果提供的密码的哈希与该用户存储在数据库中的哈希匹配,则身份验证将成功。在这种情况下,该方法将通过调用createJwtPayload方法返回JWT。 createJwtPayload方法会将用户的电子邮件地址添加到有效负载中,然后使用注入到构造函数中的JwtService的sign方法对JWT进行签名。
但是,我遇到了一个错误:
src/auth/auth.service.ts:23:23 - error TS2339: Property 'checkPassword' does not exist on type'User'.
23 userToAttempt.checkPassword(loginAttempt.password, (err, isMatch) => {
能否请您确定问题出在哪里?