我已经设置了Passport来验证存储在mongodb中的用户。似乎工作正常:身份验证成功/失败,会话变量设置。但是,让Passport检查会话是否失败。我添加到deserializeUser
回调中的console.log语句从来没有看到过光明的事情,这似乎是完全错误的。我认为我的问题与deserializeUser
从未被调用有关。有人能够诊断我的错误吗?
// Passport configuration
passport.serializeUser(function(user, cb){ cb(null, user.id) });
passport.deserializeUser(function(uid, cb){
console.log("Trying to deserialize user: "+uid);
User.findById(uid, function(err, user){
cb(err, user);
});
});
// auth strategy function
passport.use(new LocalStrategy({usernameField: 'email'},
function(email, pass, done){
User.findOne({email: email}, function (err, user) {
if (err)
return done(err);
if (!user)
return done(null, false, {message: "Couldn't find user"});
var crypted = bcrypt.hashSync(pass, user.salt);
if(user.hashpass != crypted)
return done(null, false, {message: "Bad password"});
return done(null, user);
});
}
));
passport.CreateSession = function (req, res, next) {
passport.authenticate('local', function(err, user, info){
if(err || !user)
return res.json({status: "Failure: "+err});
req.logIn(user, function (err){
if(err)
return res.json({status: "Failure: "+err});
return res.json({status: "Authenticated"});
});
})(req, res, next);
};
在app.js中有以下内容:
app.post('/session', passport.CreateSession); // restify better
app.del('/session', passport.DestroySession);
app.get('/images', passport.CheckSession, routes.images);
答案 0 :(得分:35)
对于遇到此问题的其他人,请看一下:
app.use(session({
secret: 'something',
cookie: {
secure: true
}}));
如果您将cookie.secure
设置为true并且您不使用SSL(即https协议),那么具有会话ID的cookie不会返回到浏览器,并且所有内容都会无声地失败。删除此标志为我解决了问题 - 需要花费数小时才能实现这一点!
答案 1 :(得分:25)
如果在使用护照进行身份验证时使用authenticate
回调,则需要手动登录用户。不会为你打电话。
passport.authenticate('local', function (err, user) {
req.logIn(user, function (err) { // <-- Log user in
return res.redirect('/');
});
})(req, res);
答案 2 :(得分:11)
您有use()
'd passport.session()
中间件吗?就像在这个例子中一样:
https://github.com/jaredhanson/passport-local/blob/v1.0.0/examples/login/app.js#L91
这就是恢复会话并调用deserializeUser
的原因,所以听起来可能会丢失。
答案 3 :(得分:2)
好的,这花了我近3天的时间来解决,这似乎很简单,至少就我而言。在调用以下命令之前,我必须先放置app.use(require('cookie-parser'));
和app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));
:
app.use(passport.initialize());
app.use(passport.session());
注意:这些代码段不是我的实际代码,我从https://github.com/passport/express-4.x-local-example> server.js文件中获取了这些代码段;但这就是要点。
答案 4 :(得分:1)
我整天都在解决同样的问题。我有一个自定义回调设置来执行授权(如http://passportjs.org/guide/authenticate/的底部)。看起来Passport在处理其他中间件之前预处理了所有请求对象(基于我写的一些日志语句)。作为预处理的一部分,它将反序列化的用户信息放入request.user对象中。不幸的是,passport.authenticate(&#39; local&#39;,回调)的默认行为似乎是忽略任何会话或cookie数据,而是假设在请求对象中发送用户名和PW。我所做的是首先检查request.user对象,如果它存在,则意味着Passport已完成预处理,然后我可以直接调用login。这是我的授权功能,我用它来代替passport.authenticate(&#39; local&#39;):
function doAuth(request, response, next)
{
if (request.user) {
request.logIn(request.user, function (err) {
if (err) {
console.log(err);
response.status(500).json({message:
"Login failed. Auth worked. Nonsense"});
return;
}
console.log("doAuth: Everything worked.");
next();
});
return;
}
passport.authenticate('local', function(err, user, info) {
if (err) {
response.status(500).json({message: "Boo Passport!"});
return; //go no further
//until I figure out what errors can get thrown
}
if (user === false) {
console.log("Authentication failed. Here is my error:");
console.log(err);
console.log("Here is my info:");
console.log(info);
response.status(500).json({message: "Authentication failed."});
return;
}
request.logIn(user, function(err) {
if (err) {
console.log("Login failed. This is the error message:");
console.log(err);
response.status(500).json({message:"Login failed."});
return;
}
console.log("doAuth: Everything worked. I don't believe it.");
next();
});
})(request, response, next);
}
答案 5 :(得分:0)
在我的情况下,这是因为我有以下代码:
app.get("/auth/google/callback",
passport.authenticate("google", {
failureRedirect: "/admin/login/?error",
}),
(req, res) => {
return res.redirect("/admin/");
},
);
显然,在这种情况下,不会调用req.login()(它将调用反序列化)。我将其更改为此并奏效了:
app.get("/auth/google/callback",
passport.authenticate("google", {
successRedirect: "/admin/",
failureRedirect: "/admin/login/?error",
})
);
答案 6 :(得分:0)
在我的情况下,我放置了
app.use(cookieSession({
maxAge : 60*60*1000,
keys : [key.cookieSession.key1]
}));
上方
app.use(passport.initialize());
app.use(passport.session());
它奏效了。
答案 7 :(得分:0)
我通过网络安全性或开放隐身模式打开了谷歌浏览器,对我来说很有效
web-security for linux /usr/bin/google-chrome-stable
--disable-web-security --user-data-dir=/home/jossnaz/.config/google-chrome/
答案 8 :(得分:0)
在 Heroku 中,所有请求都以纯http形式进入应用程序,但是带有X-Forwarded-Proto标头以了解原始请求是http还是https。
这会导致Express看到非SSL流量,因此在Heroku上运行时拒绝设置安全cookie。您必须通过设置“信任代理”来告诉express信任该标头中的信息。
app.set('trust proxy', 1);
就在
之前app.use(session...
如果您在Heroku上遇到麻烦,可以为您工作。如果您的Cookie /会话混乱了,那可能就是为什么不调用反序列化的原因。
答案 9 :(得分:-1)
确保代码行app.use(express.static(path.join(__dirname, 'public')));
低于app.use(require('express-session')
答案 10 :(得分:-1)
你必须先配置 session,然后在 configinitialize() 和 session() 之后配置
// config session first
app.use(session({
secret: 'something',
cookie: {
secure: true
}}));
// after configinitialize() and session()
app.use(passport.initialize())
app.use(passport.session())
答案 11 :(得分:-3)
passport.serializeUser(
function(user, done){
done(null, user.id);
});
passport.deserializeUser(
function(id, done){
User.findById(id, function(err, user){
if(err){
done(err);
}
done(null, user);
});
});
**> try this one**