Nodejs,bcrypt async,mongoose登录

问题描述 投票:1回答:1

我有用户模型的以下代码

const userSchema = mongoose.Schema({

_id: mongoose.Schema.Types.ObjectId,
username: {
    type: String,
    required: true,
    trim: true,
    minlength: 3,

},
email: {
    type: String,
    required: true
},
password: {
    type: String,
    required: true
}

})

然后为了哈希密码我有这个代码

UserSchema.pre('save', function (next) {


if (this.isModified('password')){

    bcrypt.genSalt(10, (err, salt)=>{

        bcrypt.hash(this.password, salt, (err, hash)=>{
            this.password = hash;
            next();
        })

    });
}
next();

})

然后,为了检查来自用户的输入值的哈希,我有以下代码

userSchema.statics.comparePassword = function(password){
    let user = this;
    return bcrypt.compareAsync(password, user.password)
}

因此,当涉及到所有这些代码片段的使用时,我有以下内容

async loginUser(req, res) {
    try{
        const {email, password} = req.body
        const user = await User.findOne({
            email: req.body.email
        })
        if(!user){
            return res.status(403).send({
                error: "Incorrect details email"
            })
        }
        const isPassValid = await user.comparePassword(password)
       }catch(err){
        res.status(403).send({
            error: "The bid deal happened"
        })
     }
}

所以我尝试在谷歌搜索和在这个论坛上找到答案,但一切似乎已经过时或不适合我的情况。这段代码总是发送“出价交易”,我试图从各方调试它,但它仍然不成功。

问题是如何使它工作?这样我就能以正确的方式比较密码

P.S我尝试从compareAsync更改为compareSync,显示无效

javascript node.js mongodb mongoose postman
1个回答
1
投票

您在更改值时加密密码,但在插入新的mongo文档时不加密,您可以使用document.isNew进行检查。

我已将您的保存方法更新为以下内容。

UsersSchema.pre('save', function (next) {
    let user = this;

    if (this.isModified('password') || this.isNew) {
        bcrypt.genSalt(10, (err, salt) => {
            if (err) {
                return next(err);
            }

            bcrypt.hash(user.password, salt, (err, hash) => {
                if (err) {
                    return next(err);
                }

                user.password = hash;
                next();
            });
        });
    } else {
        next();
    }
});

此外,Schema.statics用于服务static方法。 this上下文不会返回用户,因此使this.password未定义。要使用方法填充模式的实例,必须将它们附加到Schema.methods对象。

我过去使用过bcrypt.compare,我不知道bcrypt.compareAsync是否是一个有效的方法,因为第一个已经是异步的。如果它是异步的,它将不会直接返回一个值。比较需要回调。

UsersSchema.methods.comparePassword = function (password, callback) {
    bcrypt.compare(password, this.password, (err, isMatch) => callback(err, isMatch));
};

要比较密码,您可以执行以下操作:

const { email, password } = req.body

User.findOne({
    email: email,
}, (err, user) => {
    if (err) throw err;

    if (user) {
        user.comparePassword(password, (err, match) => {
            if (match && !err) {
                // match
            }
        });
    }
});
© www.soinside.com 2019 - 2024. All rights reserved.