metode bukan masalah metode fungsi Mongoose

Jan 03 2021

ENV:

node v12.19.0

Mongo Atlas V4.2.11.0

luwak V5.11.8

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

Saya memiliki Skema pengguna

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

Saya memeriksa apakah kata sandi tidak diubah maka saya memodifikasinya sebelum disimpan.

dan saya menambahkan metode untuk membandingkan kata sandi dengan kata sandi berciri yang disebut bandingkanPassword

Saya mencoba menggunakan metode bandingkanPassword di file lain

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

ketika saya mencoba membandingkan kata sandi dengan metode yang telah ditentukan, ia mengembalikan ini dalam respons

user.comparePassword bukanlah sebuah fungsi

Saya melihat berbagai solusi.

beberapa mengatakan bahwa ini berhasil untuk mereka:

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

tetapi tidak berhasil. Saya juga mencoba solusi yang berbeda tetapi saya tidak yakin apa yang salah dengan kodenya.

Pembaruan 1:

Saya mencoba menggunakan statika dan tidak berhasil

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

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

Jawaban

AhmedGaafer Jan 04 2021 at 01:12

Di Auth.js

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

ini salah karena kita harus menunggu kueri selesai;

seharusnya seperti ini

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