简体   繁体   English

Mongoose 方法和 Typescript - 此属性未定义

[英]Mongoose Methods and Typescript - this property is undefined

I'm developing a typescript app a restful api using node,express and mongoose.我正在使用 node、express 和 mongoose 开发一个打字稿应用程序一个宁静的 api。

I have an auth controller with a store function attached to POST: /api/auth .我有一个身份验证控制器,带有附加到POST: /api/auth的存储功能。 The user passes in their email and password to compare it against the hashed version.用户传入他们的电子邮件和密码以将其与散列版本进行比较。

However the comparePassword function in the use.model.ts doesent work because this.password is undefined.但是use.model.ts的 comparePassword 函数不起作用,因为this.password未定义。

auth.controller.ts 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用户模型.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;

I have similar comparePassword function working in another project that doesn't use typescript.我在另一个不使用打字稿的项目中使用了类似的 comparePassword 函数。 So im not sure why "this" is undefined and is not set to the mongoose user object.所以我不确定为什么“this”是未定义的并且没有设置为猫鼬用户对象。

Here's what I do to bypass that typescript issue.这是我为绕过打字稿问题所做的工作。

const self:any = this; const self:any = this;

Usage example:用法示例:

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);
    });
};

Also if you're in a rush and don't want to create an interface you can do this on your pre events.此外,如果您很着急并且不想创建界面,您可以在您的活动进行此操作。

UserSchema.pre<any>('save', function(next) {
   if (!this.isModified('password')) 
       return next();
   ...
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM