Мой 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, который совпадает с предоставленным адресом электронной почты, а затем вызывает пользовательский метод 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);
});
};
Если ha sh предоставленного пароля совпадает с ha sh, хранящимся в базе данных для этого пользователя, аутентификация будет успешной. В этом случае метод вернет JWT, вызвав метод createJwtPayload. Метод createJwtPayload добавит адрес электронной почты пользователя к полезной нагрузке, а затем подпишет JWT, используя метод подписи JwtService, который был введен в конструктор.
Однако я получил ошибку:
src/auth/auth.service.ts:23:23 - error TS2339: Property 'checkPassword' does not exist on type'User'.
23 userToAttempt.checkPassword(loginAttempt.password, (err, isMatch) => {
Не могли бы вы определить, в чем проблема?