序列化用户后,带 Sequelize 和 Express 的 PassportJS(Local) 卡在待定状态

PassportJS(Local) with Sequelize and Express stuck on pending after serializing user

我正在尝试使用我在 http://code.tutsplus.com/tutorials/authenticating-nodejs-applications-with-passport--cms-21619 中找到的教程进行登录。我修改了代码以使用 Sequelize。我能够验证用户名和密码,但在序列化用户后,它重定向到的页面不会加载。我想知道我是否遗漏了什么。

我并没有真正收到错误,但是重定向到 /test/home 页面一直处于挂起状态,它一直在执行 post 请求。它似乎也 运行 req.isAuthenticated()

Executing (default): SELECT "id", "email", "username", "password" FROM "users" AS "user" WHERE "user"."username" = 'user14' LIMIT 1;
username and password matched
serializing user: 
POST /test/login 302 377.738 ms - 64
Executing (default): SELECT "id", "email", "username", "password" FROM "users" AS "user" WHERE "user"."id" = 16;
GET /test/home - - ms - -
Executing (default): SELECT "id", "email", "username", "password" FROM "users" AS "user" WHERE "user"."id" = 16;
POST /test/home - - ms - -
Executing (default): SELECT "id", "email", "username", "password" FROM "users" AS "user" WHERE "user"."id" = 16;
POST /test/home - - ms - -

这是我的 app.js 的片段:

// configuring passport
var passport = require('passport');
var expressSession = require('express-session');
app.use(expressSession({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());

// initialize passport
var initPassport = require('./passport/init');
initPassport(passport);

// routes
var routes = require('./routes/index');
var loginTest = require('./routes/test')(passport);
var gameRoute = require('./routes/game');
app.use('/', routes);
app.use('/test', loginTest);
app.use('/game', gameRoute);

init.js:

var login = require('./login');
var User = require('../server/models/index').user;

module.exports = function(passport){
    passport.serializeUser(function(user, done) {
        console.log('serializing user: ');
        done(null, user.get('id'));
    });

    passport.deserializeUser(function(id, done) {
        User.findById(id, function(err, user) {
            console.log('deserializing user:',user);
            done(err, user);
        });
    });

    // setting up Passport Strategies for Login
    login(passport);

}

test.js(路由器)

var express = require('express');
var router = express.Router();

var isAuthenticated = function (req, res, next) {
    if (req.isAuthenticated())
        return next();
    res.redirect('/test');
}

module.exports = function(passport){

    router.post('/login', passport.authenticate('login', {
        successRedirect: '/test/home',
        failureRedirect: '/test',
        failureFlash : true  
    }));


    /* GET Home Page */
    router.get('/home', isAuthenticated, function(req, res){
        res.render('home', { user: req.user });
    });

    return router;
}

login.js

var LocalStrategy   = require('passport-local').Strategy;
var User = require('../server/models/index').user;
var bCrypt = require('bcrypt-nodejs');

module.exports = function(passport){

    passport.use('login', new LocalStrategy({
          passReqToCallback : true
      },
      function(req, username, password, done) { 
        // check if user with username exists or not
        User.findOne({ 
          where: {
            username:  username 
          }
        }).then(function(user) {
            if (!user){
              console.log('User Not Found with username '+username);
              return done(null, false, { message: 'Incorrect username.' });       
            }
            if (!isValidPassword(user, password)){
              console.log('Invalid Password');
              return done(null, false, { message: 'Incorrect password.' });
            }
            console.log('username and password matched');
            return done(null, user);
          }
        );

      })
  );

  var isValidPassword = function(user, password){
    return bCrypt.compareSync(password, user.password);
  }

}

经过一些研究,我意识到导致问题的原因是 deserializing。我的 console.log 没有给我错误,因为它停留在 User.findById(...)。 Sequelize 不是 return 回调,而是一个承诺。

而不是将其用于 init.js,

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    console.log('deserializing user:',user);
    done(err, user);
  });
});

改用此语法

passport.deserializeUser(function(id, done) {
  User.findById(id).then(function(user) {
    console.log('deserializing user:',user);
    done(null, user);
  }).catch(function(err) {
    if (err) {
      throw err;
    }
 });
});