我正在尝试使用护照本地身份验证和续集。当我提交登录表单时,请求/响应周期永远不会结束,并且终端中没有错误消息。
以下是我的所有代码:
app.js
var Sequelize = require('sequelize'),
express = require('express'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
User = require('./models/users');
........ and other imports.....
//route import , model injection
var auth = require('./routes/auth')(User);
.......................
app.use(session({
store: new RedisStore(),
secret: 'keyboard cat',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
console.log(user);
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id).then(function(user){
done(null, user);
}).catch(function(e){
done(e, false);
});
});
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({where: {username: username}}).then(function(err, user) {
if (err) { return done(err); }
if (!user) {
console.log('Incorrect username.');
return done(null, false, { message: 'Incorrect username.' });
} else if (password != user.password) {
console.log('Incorrect password');
return done(null, false, { message: 'Incorrect password.' });
} else {
console.log('ok');
done(null, user);
}
});
}
));
和routes / auth.js:
var express = require('express'),
passport = require('passport');
var routes = function(User) {
var router = express.Router();
// routes for registration
router.route('/register')
.get(function(req, res) {
res.render('register');
})
.post(function(req, res) {
User.count().then(function(number) {
if (number >= 1) {
res.redirect('/auth/login');
} else {
User.create({
username: req.body.username,
password: req.body.password
});
res.redirect('/auth/login');
}
});
});
//routes for login
router.route('/login')
.get(function(req, res) {
res.render('login');
})
.post(function(req, res) {
passport.authenticate('local', { successRedirect: '/dashboard',
failureRedirect: '/auth/login' });
});
return router;
};
module.exports = routes;
答案 0 :(得分:2)
为什么请求/响应周期永远不会结束?
您当前的中间件定义为' ./ login' POST不正确,不发送响应,这就是为什么它不会结束(直到它超时)。
不是在中间件函数中调用passport.authenticate
,而是调用passport.authenticate
的结果应该用作中间件本身。我建议如下:
router.route('/login')
.get(function(req, res) {
res.render('login');
})
.post(passport.authenticate('local', { successRedirect: '/dashboard',
failureRedirect: '/auth/login' });
);
有关示例,请参阅http://passportjs.org/docs/authenticate。
注册码中的竞争条件
你没有问过这个问题,但是你的中间件存在竞争条件,因为' ./ register' POST。
User.create
返回保存创建的用户的承诺。在该承诺得到解决之前,无法保证用户存在于后备数据存储区中。但是,在调用create之后,您的代码会立即重定向到登录端点,该端点将查询该用户的数据库。
以下是一些避免此问题的代码:
User.create({ ... })
.then(function() {
res.redirect('/auth/login');
})
.catch(function(err) {
// Handle rejected promise here
})
包含catch
,因为处理被拒绝的承诺和抛出异常始终是一种好习惯。