使用本地策略进行身份验证时,Passportjs会丢失500服务器错误

时间:2015-06-25 20:55:16

标签: node.js authentication passport.js passport-local

我正在尝试使用Facebook和本地策略进行多策略验证。 facebook auth通常正常工作,我的数据库得到更新,但本地策略给了我以下错误:

  TypeError: undefined is not a function
   at allFailed (/Users/r/Desktop/jb/node_modules/passport/lib/middleware/authenticate.js:111:15)
   at attempt (/Users/r/Desktop/jb/node_modules/passport/lib/middleware/authenticate.js:160:28)
   at Strategy.strategy.fail (/Users/r/Desktop/jb/node_modules/passport/lib/middleware/authenticate.js:277:9)
   at Strategy.authenticate (/Users/r/Desktop/jb/node_modules/passport-local/lib/strategy.js:75:17)
   at attempt (/Users/r/Desktop/jb/node_modules/passport/lib/middleware/authenticate.js:341:16)
   at authenticate (/Users/r/Desktop/jb/node_modules/passport/lib/middleware/authenticate.js:342:7)
   at Layer.handle [as handle_request] (/Users/r/Desktop/jb/node_modules/express/lib/router/layer.js:82:5)
   at next (/Users/r/Desktop/jb/node_modules/express/lib/router/route.js:110:13)
   at Route.dispatch (/Users/r/Desktop/jb/node_modules/express/lib/router/route.js:91:3)
   at Layer.handle [as handle_request] (/Users/r/Desktop/jb/node_modules/express/lib/router/layer.js:82:5)
   at /Users/r/Desktop/jb/node_modules/express/lib/router/index.js:267:22
   at Function.proto.process_params (/Users/r/Desktop/jb/node_modules/express/lib/router/index.js:321:12)
   at next (/Users/r/Desktop/jb/node_modules/express/lib/router/index.js:261:10)
   at SessionStrategy.strategy.pass (/Users/r/Desktop/jb/node_modules/passport/lib/middleware/authenticate.js:318:9)
   at SessionStrategy.authenticate (/Users/r/Desktop/jb/node_modules/passport/lib/strategies/session.js:67:10)
   at attempt (/Users/r/Desktop/jb/node_modules/passport/lib/middleware/authenticate.js:341:16)

这是代码本身:

'use strict';

var passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
var LocalStrategy = require('passport-local').Strategy;

module.exports = function(app, User) {

  app.use(passport.initialize());
  // Enable sessions
  app.use(passport.session());

  passport.use(new LocalStrategy(
    function(username, password, done) {
      User.findOne({ username: username }, function (err, user) {
        if (err) { return done(err); }
        if (!user) { return done(null, false); }
        if (!user.verifyPassword(password)) { return done(null, false); }
        return done(null, user);
      });
    }
  ));

  passport.use(new FacebookStrategy({
      clientID: 1234544646,
      clientSecret: "sertysehtrhr345345345234234",
      callbackURL: "http://localhost:5000/auth/facebook/callback"
    },
    function(accesstoken, tokenSecret, profile, done) {
      // Could be an existing user or a new user
      // profile.username is used as the username
      User.findOrCreate({
        where: {
          username: profile.id,
          email: profile.emails[0].value,
          displayName: profile.displayName
        }
      }).spread(function(user) {
        return done(null, user);
      });
    }));

  // This just stores the username is an encrypted browser cookie
  passport.serializeUser(function(user, done) {
    done(null, user.username);
  });

  // This fetches the user by username retrieved from the
  // cookie that was set during serializeUser
  passport.deserializeUser(function(uname, done) {
    console.log(uname)
    User.find({
      where: {
        username: uname
      }
    }).then(function(user) {
      if (!user) return done(new Error('Invalid user'));
      return done(null, user);
    });
  });

  // Redirect the user to facebook for authentication. When complete, Facebook
  // will redirect the user back to the application at /auth/facebook/callback
  //app.get('/auth/facebook', passport.authenticate('facebook'));

  app.get('/auth/facebook',
  passport.authenticate('facebook', { scope: ['email']}),
      function(req, res){
  });
  // Facebook will redirect the user to this URL after approval. Finish the
  // authentication process by attempting to obtain an access token. If access
  // was granted, the user will be logged in. Otherwise, authentication has failed.
  app.get('/auth/facebook/callback',
    passport.authenticate('facebook', {
      failureRedirect: '/login'
    }),
    function(req, res) {
      res.cookie('signIn', 'true');
      res.redirect('/');
    }
  );

  app.get('/api/users', function(req, res) {
     res.render({
         message: req.flash('loginMessage')
     });
  });

  app.post('/api/users',
    passport.authenticate('local', {
        successRedirect: '/',
        failureRedirect: '/login',
        failureFlash: true
    })
  );

  // This is the middleware that needs to be used for
  // protecting APIs that require authorization
  return function(req, res, next) {
    // if user is authenticated in the session, carry on
    if (req.isAuthenticated())
      return next();

    // if they aren't redirect them to the login page /auth/twitter
    res.redirect('/');
  };
};

我正在为/ api / users做一个帖子。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您已将failureFlash设为true。这需要connect-flash中间件。 Express 2.x自己有这个,而在Express 3.x它有一个单独的模块。 因此,要么将failureFlash选项设置为false,要么使用connect-flash

这是Passport docs对此

所说的内容
  

注意:使用Flash消息需要req.flash()功能。表达   2.x提供了此功能,但它已从Express 3.x中删除。建议使用connect-flash中间件在使用Express 3.x时提供此功能。