【问题标题】:Can't use prototypes or instance methods in Sequelize v6无法在 Sequelize v6 中使用原型或实例方法
【发布时间】:2020-07-21 01:52:55
【问题描述】:

我将 passport.js 与 Sequelize 版本 6.3.3 结合使用。模型文件是使用 sequelize-cli 搭建的,我有以下问题: 我无法使用我在模型类上定义的实例方法或原型方法。我不断收到错误“model.methodName 不是函数”。

这是我的模型的代码: 用户.js

'use strict';
const { Model } = require('sequelize');
const bcrypt = require('bcryptjs');

module.exports = (sequelize, DataTypes) => {
    class User extends Model {
        static associate(models) {
            // define association here
        }

        testInstanceMethod() {
            console.log('Test passed');
        }
    }

    User.init(
        {
            email: {
                type: DataTypes.STRING,
                notNull: true,
                unique: true,
                validate: {
                    isEmail: {
                        args: true,
                        msg: 'Please enter a valid email',
                    },
                },
            },
            password: {
                type: DataTypes.STRING,
                notNull: true,
                validate: {
                    len: {
                        args: [8, 255],
                        msg: 'Password must be 8+ characters long',
                    },
                },
            },
        },
        {
            sequelize,
            modelName: 'User',
        }
    );

    // Hash password before user is created
    User.addHook('beforeCreate', async (user, options, next) => {
        try {
            // generate a salt
            const salt = await bcrypt.genSalt(10);
            // hash the password using the salt we generated above
            const hashedPassword = await bcrypt.hash(user.password, salt);
            // set user's password to the hashed password
            user.password = hashedPassword;
        } catch (error) {
            console.log(error);
            next(error);
        }
    });

    User.prototype.isValidPassword = async (user, userInputtedPassword) => {
        try {
            return await bcrypt.compare(userInputtedPassword, user.password);
        } catch (error) {
            throw new Error(error);
        }
    };

    return User;
};

passport.js

const passport = require('passport');
const JwtStrategy = require('passport-jwt').Strategy;
const ExtractJwt = require('passport-jwt').ExtractJwt;
const db = require('../../models');
const LocalStrategy = require('passport-local');

/* ******************* */
// HANDLE JWT
/* ****************** */

// Passport jwt options object
let options = {};
// grab jwt from the header
options.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
options.secretOrKey = process.env.TOKEN_SECRET;

// Configure and use passport.js
passport.use(
    new JwtStrategy(options, async (jwtPayload, done) => {
        try {
            // find user with an id matching the jwt subscriber id
            const user = await db.User.findAll({ where: { id: jwtPayload.sub } });
            if (user) {
                // if user is found, return it
                return done(null, user);
            } else {
                // if not found, return false
                done(null, false);
            }
        } catch (error) {
            // catch errors
            done(error, false);
        }
    })
);

/* ******************* */
// LOCAL STRATEGY
/* ****************** */
passport.use(
    new LocalStrategy(
        {
            usernameField: 'email',
        },
        async (email, password, done) => {
            try {
                // find user when given the email
                const user = await db.User.findAll({ where: { email: email } });

                // if no user is found. handle it
                if (!user) {
                    return done(null, false);
                }

                // test instance method
                user.testInstanceMethod();

                const passwordMatch = await user.isValidPassword(password);
                // if password doesn't match then handle it
                if (!passwordMatch) {
                    return done(null, false);
                }

                console.log('successful login');
                return done(null, user);
            } catch (error) {
                return done(error);
            }
        }
    )
);

如果考虑 passport.js 文件中的代码,实例级方法 (testInstanceMethod) 会抛出错误“Type error user.testInstanceMethod is not a function”。如果您注释掉该行,原型方法 (isValidPassword) 会抛出错误“Type error user.isValidPassword is not a function”。我做错了什么?

【问题讨论】:

    标签: node.js express sequelize.js passport.js sequelize-cli


    【解决方案1】:

    您应该让one 用户访问其方法:

    // users is an array, see findAll method in Sequelize documentation
    const users = await db.User.findAll({ where: { email: email } });
    if (!users.length) {
      return done(null, false);
    }
    
    // test instance method
    users[0].testInstanceMethod();
    
    const passwordMatch = await users[0].isValidPassword(password);
    

    如果您有一个用户使用特定电子邮件,则最好使用 findOne

    const user = await db.User.findOne({ where: { email: email } });
    if (!user) {
      return done(null, false);
    }
    
    // test instance method
    user.testInstanceMethod();
    
    const passwordMatch = await user.isValidPassword(password);
    
    

    【讨论】:

      猜你喜欢
      • 2013-10-26
      • 2017-10-12
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      相关资源
      最近更新 更多