使用 sequelize 的 passport js 本地身份验证
passport js local authentication using sequelize
我正在尝试将护照本地身份验证与 sequelize 结合使用。当我提交登录表单时,request/respond 循环永远不会结束,终端中也没有错误消息。
这是我所有的代码:
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;
为什么 request/response 循环永远不会结束?
您当前对“./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
returns 保存创建用户的承诺。在该承诺得到解决之前,无法保证用户存在于后备数据存储中。但是,在调用创建之后,您的代码立即重定向到登录端点,该端点将查询该用户的数据库。
这里有一些代码可以避免这个问题:
User.create({ ... })
.then(function() {
res.redirect('/auth/login');
})
.catch(function(err) {
// Handle rejected promise here
})
包含 catch
是因为处理被拒绝的承诺和抛出的异常始终是一种好的做法。
我正在尝试将护照本地身份验证与 sequelize 结合使用。当我提交登录表单时,request/respond 循环永远不会结束,终端中也没有错误消息。
这是我所有的代码:
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;
为什么 request/response 循环永远不会结束?
您当前对“./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
returns 保存创建用户的承诺。在该承诺得到解决之前,无法保证用户存在于后备数据存储中。但是,在调用创建之后,您的代码立即重定向到登录端点,该端点将查询该用户的数据库。
这里有一些代码可以避免这个问题:
User.create({ ... })
.then(function() {
res.redirect('/auth/login');
})
.catch(function(err) {
// Handle rejected promise here
})
包含 catch
是因为处理被拒绝的承诺和抛出的异常始终是一种好的做法。