我正在使用node,express和mongoose开发一个带有restcript api的打字稿应用程序。
我有一个auth控制器,其存储功能附加到POST: /api/auth
。用户传入他们的电子邮件和密码,将其与散列版本进行比较。
然而use.model.ts
doesent中的comparePassword函数的工作原因是this.password
未定义。
auth.controller.ts
import { Request, Response, NextFunction } from 'express';
import User from './../users/user.model';
import jwt from 'jsonwebtoken';
import Config from './../../config/config';
class AuthController {
private config: any;
constructor() {
this.config = new Config();
}
public async store(req: Request, res: Response): Promise<any> {
const input = req.body;
console.log(input);
try {
let user = await User.findOne({ 'email': input.email });
if (!user) {
throw {};
}
console.log(user);
user.schema.methods.comparePassword(input.password, (err: any, isMatch: any) => {
if (err || !isMatch) {
return res.status(401).json({
success: false,
status: 401,
data: { err, isMatch },
message: 'Authentication Failed, wrong password',
});
}
if (!err && isMatch) {
const token = jwt.sign({ sub: user._id }, this.config.jwt.secretOrKey);
return res.status(200).json({
success: true,
status: 200,
data: { user, token },
message: 'Authentication Successful',
})
}
})
} catch (err) {
return res.status(404).json({
success: false,
status: 404,
data: err,
message: 'Failed to Authenticate'
})
}
}
}
export default AuthController;
user.model.ts
import { Schema, Model, Document, model } from 'mongoose';
import bcrypt from 'bcryptjs';
import { UserInterface } from './user.interface';
const UserSchema = new Schema({
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
}, {
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' },
});
UserSchema.pre('save', function (next) {
let user = <UserInterface>this;
let SALT_WORK_FACTOR = 10;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();
// generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
if (err) return next(err);
// hash the password using our new salt
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) return next(err);
// override the cleartext password with the hashed one
user.password = hash;
next();
});
});
});
UserSchema.methods.comparePassword = function (candidatePassword: any, cb: any) {
//let user = <UserInterface>this;
console.log(candidatePassword);
console.log(this.password);
bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
const User = model<UserInterface>('Users', UserSchema);
export default User;
我有一个类似的comparePassword函数在另一个不使用typescript的项目中工作。所以我不确定为什么“this”未定义且未设置为mongoose用户对象。
答案 0 :(得分:0)
这是我为绕过打字稿问题所做的工作。
<块引用>const self:any = this;
使用示例:
UserSchema.methods.comparePassword = function (candidatePassword: any, cb: any) {
const self:any = this;
console.log(candidatePassword);
console.log(self.password);
bcrypt.compare(candidatePassword, self.password, function (err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
此外,如果您很着急并且不想创建界面,您可以在预活动中执行此操作。
UserSchema.pre<any>('save', function(next) {
if (!this.isModified('password'))
return next();
...
})