JS认为函数是未定义的,即使它显然存在

时间:2015-09-22 00:48:13

标签: javascript node.js express bookshelf.js

此问题与Function is undefined, Bookshelf.js model function is not being recognized as a function

有关

我使用Bookshelf.js来处理用NodeJS和ExpressJS构建的用户注册/登录API端点。但是,在POST到登录路由时,Bookshelf会抛出以下错误:

Unhandled rejection TypeError: undefined is not a function
    at \routes\index.js:217:36
    at Strategy.strategy.success (\node_modules\passport\lib\middleware\authenticate.js:194:18)
    at verified (\node_modules\passport-local\lib\strategy.js:83:10)
    at null.<anonymous> (\config\passport.js:17:20)

...

以下是routes / index.js

var User = require('./models/User');
router.post('/login', function(req, res, next){
  if(!req.body.username || !req.body.password){
    return res.status(400).json({message: 'Please fill out all fields'});
  }
  passport.authenticate('local', function(err, user, info){
    if(err){ return next(err); }
    if(user){
      return res.json({token: user.generateJWT()});
    } else {
      return res.status(401).json(info);
    }
  })(req, res, next);
});

以下是models / Users.js

var jwt = require('jsonwebtoken');
var bcrypt = require('bcrypt');
var bookshelf = require('../config/bookshelf');

var User = bookshelf.Model.extend({
  tableName: 'users',
  validPassword: function(password, encryptedPass) {
    return new Promise(function (resolve, reject) {
      bcrypt.compare(password, encryptedPass, function (err, match) {
        if(err) return reject(err);
        resolve(match);
      });
    });
  },
  generateJWT: function() {
    // set expiration to 60 days
    var today = new Date();
    var exp = new Date(today);
    exp.setDate(today.getDate() + 60);

    return jwt.sign({
      _id: this._id,
      email: this.email,
      exp: parseInt(exp.getTime() / 1000),
    }, 'SECRET');
  }
}, {
  createPassword: function (password) {
    return new Promise(function (resolve, reject) {
      bcrypt.genSalt(10, function (err, salt) {
        if (err) return reject(err);
        bcrypt.hash(password, salt, function (err, hash) {
          if (err) return reject(err);
          resolve(hash);
        });
      });
    });
  }
});

module.exports = User;

这是config / passport.js

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/Users');

passport.use(new LocalStrategy(
  function(email, password, done) {
    new User({email: email}).fetch().then(function(data) {
      var user = data;
      var curr_user = this;
      if(user === null) {
         return done(null, false, {message: 'Invalid username or password'});
      } else {
         user = data.toJSON();
         if (!curr_user.validPassword(password)) {
            return done(null, false, {message: 'Invalid username or password'});
         } else {
            return done(null, user);
         }
      }
    });
  }
));

这是异步/承诺问题吗?或者我在其他地方出错了?

1 个答案:

答案 0 :(得分:0)

不知道是什么 at \routes\index.js:217:36,开始尝试回答这个问题非常困难。

编辑:但是,at Strategy.strategy.success确实表明这是一个未返回Promise的问题。换句话说,你可能正在做类似

的事情
ThinkingYouAreReturningAPromiseInThisFunction
  .success(function(result) {
    // stuff
  });

但实际上并没有在ThinkingYouAreReturningAPromiseInThisFunction()中返回Promise对象。换句话说,success()不是函数。通常,Promise对象的方法类似于success()。但是如果没有返回这样的对象,那么undefined is not a function。我会在那里开始排除故障。