node.js 护照的 req.isAuthenticated 总是返回 false,即使我硬编码 done(null, true)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29111571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
passport's req.isAuthenticated always returning false, even when I hardcode done(null, true)
提问by CodyBugstein
I'm trying to get my Passport local strategy working.
我正在努力使我的 Passport 本地策略发挥作用。
I've got this middleware set up:
我已经设置了这个中间件:
passport.use(new LocalStrategy(function(username, password, done) {
//return done(null, user);
if (username=='ben' && password=='benny'){
console.log("Password correct");
return done(null, true);
}
else
return done(null, false, {message: "Incorrect Login"});
}));
but then in here
但是在这里
app.use('/admin', adminIsLoggedIn, admin);
function adminIsLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
it always fails and redirects to the home page.
它总是失败并重定向到主页。
I can't figure out why this is happening? Why won't it authenticate?
我不明白为什么会这样?为什么不认证?
In my console I can see that's Password Correctis printing.
Why won't it work?
在我的控制台中,我可以看到Password Correct正在打印。为什么它不起作用?
回答by Nitin
I had a similar issue. Could be due to the express-session middleware needed for passport. Fixed it by using middlewares in the following order: (Express 4)
我有一个类似的问题。可能是由于护照所需的快速会话中间件。按以下顺序使用中间件修复它:(Express 4)
var session = require('express-session');
// required for passport session
app.use(session({
secret: 'secrettexthere',
saveUninitialized: true,
resave: true,
// using store session on MongoDB using express-session + connect
store: new MongoStore({
url: config.urlMongo,
collection: 'sessions'
})
}));
// Init passport authentication
app.use(passport.initialize());
// persistent login sessions
app.use(passport.session());
回答by PRAKASH THOMAS VARGHESE
FOR NEWBIES
给新手
I was facing a similar problem, where my isAuthenticated() function would return false.I lost a lot of time, hope this answer saves yours.
我遇到了类似的问题,我的 isAuthenticated() 函数会返回 false。我浪费了很多时间,希望这个答案能拯救你。
Some Common problems to watch out for,
一些需要注意的常见问题,
- Middleware setup order (express-session > pass.initialize > pass.session ).
- Serialize and Deserialize methods needs to pass user on the request.(For more info I've posted an answer on this link.. Basics of Passport Session (expressjs)-why do we need to serialize and deserialize?) if there's no user on request then isAuthenticated would return false.... and redirect to the PATH defined ......when false....
- The getUserByIdor findByIdfunction defined in the model(user.js) needs to have a User.findById (and not User.findOne) function defined.(this function would load user on the request in every session)
- 中间件设置顺序(express-session > pass.initialize > pass.session)。
- Serialize 和 Deserialize 方法需要在请求时传递用户。(有关更多信息,我已在此链接上发布了答案.. Passport Session (expressjs) 的基础知识 - 为什么我们需要序列化和反序列化?)如果没有用户request then isAuthenticated 将返回 false.... 并重定向到定义的 PATH ......when false....
- 在模型(user.js)中定义的getUserById或findById函数需要定义一个 User.findById(而不是 User.findOne)函数。(这个函数会在每个会话的请求上加载用户)
回答by Alex H
This could also be an issue with your client's POST/GET calls. I had this exact same issue but it turned out that I had to give fetch(which is what I was using) the option credentials:'include'like so:
这也可能是您客户的 POST/GET 调用的问题。我遇到了完全相同的问题,但结果证明我必须提供fetch(这是我正在使用的)选项,credentials:'include'如下所示:
fetch('/...', {
method: 'POST',
headers: myHeaders,
credentials: 'include',
body: ...
...})
The reason is because fetch doesn't support passing down cookies, which is necessary in this case.
原因是因为 fetch 不支持传递 cookie,这在这种情况下是必需的。
回答by Thomas Lindauer
My problem was that i set cookie.secure to true even if data was not over https.
我的问题是,即使数据不是通过 https 传输的,我也将 cookie.secure 设置为 true。
app.use(require('express-session')({
secret: process.env.sessionSecret,
cookie: {
maxAge: 1000 * 60 * 60 * 24 * 7 // 1 week
},
store: store,
resave: false,
saveUninitialized: false,
cookie: { secure: false } // Remember to set this
}));
Remember to set cookies to false if you're not using https
如果您不使用 https,请记住将 cookie 设置为 false
cookie: { secure: false } // Set to false
Also if you do believe you have https remember to trust the proxy
此外,如果您确实相信您有 https,请记住信任代理
app.set('trust proxy', 1) // trust first proxy
回答by ozgeneral
I had the same issue by forgetting to add
我忘记添加也遇到了同样的问题
request.login()
on
在
app.post('/login',
function(request, response, next) {
console.log(request.session)
passport.authenticate('login',
function(err, user, info) {
if(!user){ response.send(info.message);}
else{
request.login(user, function(error) {
if (error) return next(error);
console.log("Request Login supossedly successful.");
return response.send('Login successful');
});
//response.send('Login successful');
}
})(request, response, next);
}
);
Hopefully that might help for others that ended up here same reason as I did.
希望这可能会帮助那些和我一样最终在这里的人。
回答by karan525
I also had the same problem, could not find any solution on the web but i figured it out.
我也遇到了同样的问题,在网上找不到任何解决方案,但我想通了。
app.use(require("express-session")({
secret: "This is the secret line",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParser.urlencoded({extended: true}));
express-session requirement and use should be before any other use. Try this i am sure this would work, worked for me!!
express-session 要求和使用应该在任何其他使用之前。试试这个我相信这会起作用,对我有用!!
回答by karan525
There's a kink in passport.js that nobody really mentions but I found out. This is why you can create an account or sign in and it authenticates fine at first but later on you find out req.useris undefinedor req.isAuthenticated()is falsethroughout the app.
没有人真正提到过passport.js 中的一个问题,但我发现了。这就是为什么您可以创建一个帐户或登录,它起初可以很好地进行身份验证,但后来您发现req.user是undefined或req.isAuthenticated()在false整个应用程序中。
After authenticating, passport.js requires you to reroute/redirect.That's how passport initializes the actual session.
身份验证后,passport.js 要求您重新路由/重定向。这就是passport 初始化实际会话的方式。
signIn(req, res, next) {
passport.authenticate("local")(req, res, function() {
if (!req.user) {
console.log("User not found!");
} else {
res.redirect("/")
console.log("signed in")
}
})
}
If you don't reroute after authenticating, it won't even start your session as a req.userand req.isAuthenticated()will be false.
如果您在身份验证后不重新路由,它甚至不会以 a 的形式启动您的会话,req.user并且req.isAuthenticated()会是错误的。
My app is a React and Node app but this is true for both Node apps and React/Node apps.
我的应用程序是 React 和 Node 应用程序,但对于 Node 应用程序和 React/Node 应用程序都是如此。
回答by Gio Romanadze
app.use( session({ secret: 'Our little secret.', resave: false, saveUninitialized: true, cookie: { secure: true } << it was extra for me }) );
app.use( session({ secret: '我们的小秘密。', resave: false, saveUninitialized: true, cookie: { secure: true } << 这对我来说是额外的 }) );
回答by BadriNarayanan Sridharan
I know its late, but I face this issue with FB login strategy. It was working fine, until suddenly it stopped working and that too just in Safari. I broke my head around all of the above solutions and nothing seemed to work. Finally chrome web console gave away a clue, wherein it still worked on chrome, then. The warning was this:
我知道为时已晚,但我在 FB 登录策略方面遇到了这个问题。它工作正常,直到突然它停止工作,而这也只是在 Safari 中。我对上述所有解决方案都感到头疼,但似乎没有任何效果。最后 chrome web 控制台给出了一个线索,然后它仍然可以在 chrome 上工作。警告是这样的:
A cookie associated with a cross-site resource at http://www.facebook.com/was set without the SameSiteattribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=Noneand Secure.
与跨站点资源关联的 cookiehttp://www.facebook.com/设置为没有该SameSite属性。未来版本的 Chrome 将仅在跨站点请求中使用SameSite=None和设置 cookie 时才传送 cookie Secure。
Only then i realized that i shouldn't set Samesite: true in the express session as it will not set the facebook cookie for login. After days of hacking, I fixed this issue by changing the samesite to "none".
直到那时我才意识到我不应该在快速会话中设置 Samesite: true ,因为它不会设置用于登录的 facebook cookie。经过几天的黑客攻击,我通过将相同站点更改为“无”来解决此问题。
Hope it helps someone, who encounters this issue in the future.
希望它可以帮助将来遇到此问题的人。
回答by Mr. Shan
Resolved in my case, I also faced the same problem, but resolved just by reordering the code as mentioned below:
在我的情况下已解决,我也遇到了同样的问题,但只需按如下所述重新排序代码即可解决:
//--------------------------------
//--------------------------------
previous code :
以前的代码:
app.use(flash())
app.use(session({
secret: 'somesecret',
resave: false,
saveUninitialized: false
}))
// using the custom middleware for storing variable in response
app.use((req, res, next) => {
res.locals.isAuthenticated = req.isAuthenticated()
next()
})
app.use(passport.initialize())
app.use(passport.session())
//--------------------------------
//--------------------------------
Refactored code : (which fixed the problem):
重构代码:(解决了问题):
app.use(flash())
app.use(session({
secret: 'somesecret',
resave: false,
saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())
// using the custom middleware for storing variable in response
app.use((req, res, next) => {
res.locals.isAuthenticated = req.isAuthenticated()
next()
})
//--------------------------------
//--------------------------------

