【问题标题】:cannot export function in Express无法在 Express 中导出功能
【发布时间】:2017-03-19 10:26:04
【问题描述】:

我正在尝试实现passport.js,问题在于模型中导出函数的方式:

用户模型文件(user.js)看起来像:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var bcrypt = require('bcrypt');

var userSchema = mongoose.Schema({
  username: String,
  password: String
});

userSchema.plugin(passportLocalMongoose);

userSchema.methods = {

    getUserByUsername: function(username, callback){
        var query = {username: username};
        userSchema.findOne(query, callback);
        /*userSchema.findOne(query, function(err, user) {
            callback(err, user);
        }); */
    },

    getUserById: function(id, callback){
        userSchema.findById(id, callback);
    },

    comparePassword: function(candidatePassword, hash, callback){
        bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
            if(err) throw err;
            callback(null, isMatch);
        });
    }
}

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

我调用模型(app.js):

// user schema/model
var User = require('./models/user.js');

我正在尝试在护照 (app.js) 中使用导出的函数:

passport.use(new localStrategy(
  function(username, password, done) {
    User.getUserByUsername(username, function(err, user){
      if(err) throw err;
      if(!user){
        return done(null, false, {message: 'Unknown User'});
    }

    User.comparePassword(password, user.password, function(err, isMatch){
      if(err) throw err;
      if(isMatch){
        return done(null, user);
      } else {
        return done(null, false, {message: 'Invalid password'});
      }
    });
   });
  }));

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.getUserById(id, function(err, user) {
    done(err, user);
  });
});

我收到了TypeError: User.getUserByUsername is not a function

我试图定义一个关于docs的函数:

User.methods.getUserByUsername = function(username, callback){
        var query = {username: username};
        User.findOne(query, callback);
    }

当我尝试登录时,同样的错误出现在控制台中..

编辑: 我添加了:

var User = mongoose.model('User', userSchema);

module.exports = {
  User: User
};

现在它适用于方法定义:

module.exports.getUserByUsername()

所以最终的模型文件看起来像:

// user model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var bcrypt = require('bcrypt');

var userSchema = mongoose.Schema({
  username: String,
  password: String
});

userSchema.plugin(passportLocalMongoose);

var User = mongoose.model('User', userSchema);

module.exports = {
  User: User
};

module.exports.createUser = function(newUser, callback){
    bcrypt.genSalt(10, function(err, salt) {
        bcrypt.hash(newUser.password, salt, function(err, hash) {
            newUser.password = hash;
            newUser.save(callback);
        });
    });
}

module.exports.getUserByUsername = function(username, callback){
    var query = {username: username};
    User.findOne(query, callback);
}

module.exports.getUserById = function(id, callback){
    User.findById(id, callback);
}

module.exports.comparePassword = function(candidatePassword, hash, callback){
    bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
        if(err) throw err;
        callback(null, isMatch);
    });
}

谢谢你们的帮助。

【问题讨论】:

  • 你如何要求它? User 是在 User 模型中定义的,但除非你做了类似 var User = require... 的事情,否则它不会在护照中?
  • 我在app.js 中使用var User = require('./models/user.js'); 引用了模型,所以护照可能可以访问模型,对吧?

标签: javascript express passport.js mean-stack passport-local


【解决方案1】:

代替

module.exports.getUserByUsername = ...

User.methods.getUserByUsername = ...

使用

User.statics.getUserByUsername = ...

http://mongoosejs.com/docs/2.7.x/docs/methods-statics.html

【讨论】:

  • 我尝试使用User.statics.getUserByUsername = function(username, callback){ var query = {username: username}; User.findOne(query, callback); } 并出现相同的错误:(
  • @corry 你把代码放在哪里了? User 必须引用架构,而不是导出后的用户。
  • 当然,架构定义为var User = new Schema({ username: String, password: String });User.statics.getUserByUsername 定义在同一个文件(user.js)中,而不是您建议的module.exports.getUserByUsername
【解决方案2】:

如果您是 NodeJS 新手,那么理解 module.exportsexports 可能会有些混乱。清楚地了解这个概念很重要,因为如果您进入认真的 nodejs 开发,您会经常遇到这个问题。 我不会在这里解释导出在 nodejs 中是如何工作的,因为 web 中有很多教程。例如;请阅读this

按照我下面的代码来解决您的问题。

//UserModel.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt');
var passportLocalMongoose = require('passport-local-mongoose');

var userSchema = mongoose.schema({
      username: String,
      password: String
});

userSchema.plugin(passportLocalMongoose);

userSchema.methods = {
    createUser: function(...){..},
    getUserByUsername: function(..){..},
    getUserById: function(..){..},
    comparePassword: function(..),{}

}

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

您可以从 UserSchema 访问方法:

//Controller.js
var User  = require('path/to/UserModel.js');
User.createUser(..,..)

有关更多详细信息,您可以参考我的存储库,看看我是如何做到的here

【讨论】:

  • 感谢您的解释,现在已经很清楚了,但仍然出现sam错误。我已经在对象中定义了 userSchema 方法,如您的示例 userSchema.methods = { getUserByUsername: function(username, callback){ var query = {username: username}; userSchema.findOne(query, callback); }, getUserById: function(id, callback){ userSchema.findById(id, callback); },... } 并在 app.js 中调用它 User.getUserByUsername(username, function(err, user){ if(err) throw err; if(!user){ return done(null, false, {message: 'Unknown User'}); }
  • 你能用你当前的代码更新这个问题吗?型号,你打电话的方式等等。我会帮你的。
猜你喜欢
  • 2021-12-15
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
  • 1970-01-01
相关资源
最近更新 更多