passport.js 未存储用户数据
passport.js user data not being stored
我已经用这个敲击键盘 10 个小时了。
我有一个简单的本地登录 nodejs 脚本,它似乎只能工作一次。
这是我的代码。
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
res.send(200);
} else {
next();
}
});
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
var sessionOpts = {
saveUninitialized: true,
resave: true,
store: new MongoStore({'db':'sessions'}),
secret: sessionSecret,
cookie : { httpOnly: true, secure : false, maxAge : (4 * 60 * 60 * 1000)}
}
app.use(cookieParser(sessionSecret)); // read cookies (needed for auth)
app.use(session(sessionOpts)); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
序列化和反序列化函数:
passport.serializeUser(function(user, done) {
//console.log(user._id) - This is working
done(null, user._id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
//console.log(user.) - This is working
var ident = id.toString();
db.accounts.findOne({'_id':ObjectId(ident)}, function(err, user) {
done(err, user);
});
});
本地登录功能:
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
db.accounts.findOne({'email':email}, function(err, user){
// if there are any errors, return the error before anything else
if (err)
return done(err);
if (!user)
return done(null, false, {'msg':'user not found'});
if (!validPassword(password, user.pass))
return done(null, false, {'msg':'incorrect password'});
// all is well, return successful user
return done(null, user);
});
}));
登录:
app.post('/login', passport.authenticate('local-login', {
failureRedirect : '/login'}),
function(req, res){
res.redirect('/profile');
});
});
身份验证检查:
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated()){
return next();
}
else{
console.log('failed');
}
}
使用它:
app.get('/authenticate', isLoggedIn, function(req, res){
console.log('FINALLY!!');
});
这是我在调试某些东西时看到的情况:
- 当我使用我的表单登录时,电子邮件和密码通过,它在数据库中找到用户并且密码匹配。
- 重定向到个人资料页面没问题。如果我输入了错误的电子邮件或密码,我会分别收到正确的失败消息。
- 当我尝试访问 /authenticate 页面时。它总是失败。
所以我查看了我的会话存储,这就是我所看到的:
"_id" : "XJiIfjjTtODchUM5Dt-J9BAVM6rDa6Ly",
"session" : {
"cookie" : {
"path" : "/",
"_expires" : ISODate("2015-06-19T08:33:15.304Z"),
"originalMaxAge" : 14400000,
"httpOnly" : true,
"secure" : false,
"expires" : ISODate("2015-06-19T08:33:15.304Z"),
"maxAge" : 14399999,
"data" : {
"originalMaxAge" : 14400000,
"expires" : ISODate("2015-06-19T08:33:15.304Z"),
"secure" : false,
"httpOnly" : true,
"domain" : null,
"path" : "/"
}
},
"passport" : {
}
},
"expires" : ISODate("2015-06-19T08:33:15.304Z")
此外,当我console.log(req.user)
时,它总是未定义。
所以会话数据在某个地方没有被传递到 express 或 passport 会话存储。
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
db.accounts.findById(id, function(err, user){
return done(err, user);
});
});
请试试这个代码,它对我有用,你可以在这里看到:
https://github.com/wangyangkobe/wangqiuke/blob/master/config/passport.js
第二个问题,请修改代码
var sessionOpts = {
saveUninitialized: true,
resave: true,
store: new MongoStore({'db':'sessions'}),
secret: sessionSecret,
cookie : { httpOnly: true, secure : false, maxAge : (4 * 60 * 60 * 1000)}
}
到
var sessionOpts = {
saveUninitialized: false,
resave: true,
store: new MongoStore({'db':'sessions'}),
secret: sessionSecret,
cookie : { httpOnly: true, secure : false, maxAge : (4 * 60 * 60 * 1000)}
}
来自文档:
saveUninitialized
Forces a session that is "uninitialized" to be saved to the store. A
session is uninitialized when it is new but not modified. Choosing
false is useful for implementing login sessions, reducing server
storage usage, or complying with laws that require permission before
setting a cookie. Choosing false will also help with race conditions
where a client makes multiple parallel requests without a session.
我已经用这个敲击键盘 10 个小时了。 我有一个简单的本地登录 nodejs 脚本,它似乎只能工作一次。
这是我的代码。
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
res.send(200);
} else {
next();
}
});
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
var sessionOpts = {
saveUninitialized: true,
resave: true,
store: new MongoStore({'db':'sessions'}),
secret: sessionSecret,
cookie : { httpOnly: true, secure : false, maxAge : (4 * 60 * 60 * 1000)}
}
app.use(cookieParser(sessionSecret)); // read cookies (needed for auth)
app.use(session(sessionOpts)); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
序列化和反序列化函数:
passport.serializeUser(function(user, done) {
//console.log(user._id) - This is working
done(null, user._id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
//console.log(user.) - This is working
var ident = id.toString();
db.accounts.findOne({'_id':ObjectId(ident)}, function(err, user) {
done(err, user);
});
});
本地登录功能:
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
db.accounts.findOne({'email':email}, function(err, user){
// if there are any errors, return the error before anything else
if (err)
return done(err);
if (!user)
return done(null, false, {'msg':'user not found'});
if (!validPassword(password, user.pass))
return done(null, false, {'msg':'incorrect password'});
// all is well, return successful user
return done(null, user);
});
}));
登录:
app.post('/login', passport.authenticate('local-login', {
failureRedirect : '/login'}),
function(req, res){
res.redirect('/profile');
});
});
身份验证检查:
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated()){
return next();
}
else{
console.log('failed');
}
}
使用它:
app.get('/authenticate', isLoggedIn, function(req, res){
console.log('FINALLY!!');
});
这是我在调试某些东西时看到的情况:
- 当我使用我的表单登录时,电子邮件和密码通过,它在数据库中找到用户并且密码匹配。
- 重定向到个人资料页面没问题。如果我输入了错误的电子邮件或密码,我会分别收到正确的失败消息。
- 当我尝试访问 /authenticate 页面时。它总是失败。
所以我查看了我的会话存储,这就是我所看到的:
"_id" : "XJiIfjjTtODchUM5Dt-J9BAVM6rDa6Ly",
"session" : {
"cookie" : {
"path" : "/",
"_expires" : ISODate("2015-06-19T08:33:15.304Z"),
"originalMaxAge" : 14400000,
"httpOnly" : true,
"secure" : false,
"expires" : ISODate("2015-06-19T08:33:15.304Z"),
"maxAge" : 14399999,
"data" : {
"originalMaxAge" : 14400000,
"expires" : ISODate("2015-06-19T08:33:15.304Z"),
"secure" : false,
"httpOnly" : true,
"domain" : null,
"path" : "/"
}
},
"passport" : {
}
},
"expires" : ISODate("2015-06-19T08:33:15.304Z")
此外,当我console.log(req.user)
时,它总是未定义。
所以会话数据在某个地方没有被传递到 express 或 passport 会话存储。
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
db.accounts.findById(id, function(err, user){
return done(err, user);
});
});
请试试这个代码,它对我有用,你可以在这里看到: https://github.com/wangyangkobe/wangqiuke/blob/master/config/passport.js
第二个问题,请修改代码
var sessionOpts = {
saveUninitialized: true,
resave: true,
store: new MongoStore({'db':'sessions'}),
secret: sessionSecret,
cookie : { httpOnly: true, secure : false, maxAge : (4 * 60 * 60 * 1000)}
}
到
var sessionOpts = {
saveUninitialized: false,
resave: true,
store: new MongoStore({'db':'sessions'}),
secret: sessionSecret,
cookie : { httpOnly: true, secure : false, maxAge : (4 * 60 * 60 * 1000)}
}
来自文档:
saveUninitialized
Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. Choosing false is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting a cookie. Choosing false will also help with race conditions where a client makes multiple parallel requests without a session.