问题
I'm trying to make login work, using the tutorial I've found in http://code.tutsplus.com/tutorials/authenticating-nodejs-applications-with-passport--cms-21619. I modified the code to work with Sequelize. I was able to verify username and password, but after serializing a user, the page that it redirects to does not load. I was wondering if there's something I missed.
I'm not really getting an error, but redirecting to /test/home page is stuck on pending, and it keeps executing a post request. It doesn't seem to run req.isAuthenticated() either
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 - -
Here's a snippet of my 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 (router)
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);
}
}
回答1:
After some research, I realised that what was causing the problem was deserializing
. My console.log was not giving me an error, because it's stuck at User.findById(...). Sequelize doesn't return a callback, but a promise instead.
Instead of using this for init.js,
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
console.log('deserializing user:',user);
done(err, user);
});
});
Use this syntax instead
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;
}
});
});
来源:https://stackoverflow.com/questions/34734583/passportjslocal-with-sequelize-and-express-stuck-on-pending-after-serializing