วิธีการไม่ใช่ปัญหาวิธีพังพอนของฟังก์ชัน

Jan 03 2021

ENV:

โหนด v12.19.0

Mongo Atlas V4.2.11

พังพอน V5.11.8

##############################################

ฉันมีสคีมาผู้ใช้

user.js

const mongoose = require('mongoose');
const bcrypt   = require('bcrypt');

const userSchema = new mongoose.Schema({
    email:{
        type: String,
        required: true,
        unique: true, 
    },
    username:{
        type: String,
        required: true,
        unique: true,
    },
    password:{
        type: String,
        required: true
    },
    profileImageUrl:{
        type: String,
    }
});

userSchema.pre('save', async function(next) {
    try{
        if(!this.isModified('password')){
            return next();
        }

        let hashedPassword = await bcrypt.hash(this.password, 10);
        this.password = hashedPassword;
        return next();

    } catch(err) {
        return next(err);
    }
});

userSchema.methods.comparePassword = async function(candidatePassword){
    try{
        return await bcrypt.compare(candidatePassword, this.password);

    } catch(err){
        throw new Error(err.message);
    }
}

userSchema.set('timestamps', true);

module.exports = mongoose.model("User", userSchema);

ฉันกำลังตรวจสอบว่ารหัสผ่านไม่ได้ถูกแก้ไขหรือไม่จากนั้นฉันจะแก้ไขรหัสผ่านก่อนการบันทึก

และฉันได้เพิ่มวิธีการเปรียบเทียบรหัสผ่านกับรหัสผ่านที่แฮชเรียกว่าComparePassword

ฉันกำลังพยายามใช้วิธีการComparePasswordในไฟล์อื่น

Auth.js


const db = require('../models');
const JWT = require("jsonwebtoken");
const CONFIGS = require('../config');

exports.signIn = async function(req, res, next){
    try{

        const user = db.User.findOne({
            email: req.body.email,
        });

        const { id, username, profileImageUrl } = user;
        const isMatch = await user.comparePassword(req.body.password) ; // here is a problem <====

        if(isMatch){
            const token = JWT.sign({
                id,
                username,
                profileImageUrl,
            }, CONFIGS.SECRET_KEY);
            return res.status(200).json({
                id,
                username,
                profileImageUrl,
                token,
            });
        }
        else{
            return next({
                status: 400,
                message: "Invalid email or password",
            });
        }
    }
    catch(err){
        return next(err);
    }
}
   

เมื่อฉันพยายามเปรียบเทียบรหัสผ่านกับวิธีการที่กำหนดไว้ล่วงหน้ามันจะส่งคืนสิ่งนี้ในการตอบสนอง

user.comparePassword ไม่ใช่ฟังก์ชัน

ฉันมองดูวิธีแก้ปัญหาต่างๆ

บางคนบอกว่าสิ่งนี้ใช้ได้กับพวกเขา:

userSchema.method('comparePassword' , async function(candidatePassword, next){
  // the logic
})

แต่มันไม่ได้ผลฉันลองวิธีแก้ปัญหาอื่นด้วย แต่ฉันไม่แน่ใจว่ามีอะไรผิดปกติกับรหัส

อัปเดต 1:

ฉันลองใช้สถิตยศาสตร์แล้วไม่ได้ผล

userSchema.statics.comparePassword = async function(candidatePassword){
    try{
        return await bcrypt.compare(candidatePassword, this.password);

    } catch(err){
        throw new Error(err.message);
    }
}

คำตอบ

AhmedGaafer Jan 04 2021 at 01:12

ในAuth.js

 const user = db.User.findOne({
            email: req.body.email,
        });

สิ่งนี้ผิดเพราะเราต้องรอให้การสืบค้นเสร็จสิ้น

มันควรจะเป็นแบบนี้

 const user = await db.User.findOne({
            email: req.body.email,
        });