我有一个使用Passport的应用程序,其中包含GraphQL端点和/logout
端点。出于某种原因,当我从GraphQL端点内部调用request.isAuthenticated()
时,我回到了true
,但是当我从/logout
端点内部进行相同的完全调用时,我回来了false
所以,我做了一些日志记录(request.session.id
),事实证明我以某种方式结束了两次会议。更奇怪的是,我的GraphQL端点使用的会话是持久的:如果我重新启动服务器,它会保留相同的ID,而/logout
中的ID会不断变化。
我认为发生的事情是持久会话是基于cookie / DB的,因此当我的客户端发出第一个请求时会恢复,而/logout
会话不是cookie - 基于并通过服务器重置。我不明白为什么我有两个会议!
以下是相关代码:
// Session setup
const store = new KnexSessionStore({ knex, tablename: 'sessions' });
app.use(
session({
cookie: { maxAge: 1000 * 60 * 60 * 24 * 5},
secret: `a secret`,
store
})
);
// Passport setup
passport.serializeUser((user, done) => done(null, user));
passport.deserializeUser((user, done) => done(null, user));
app.use(passport.initialize());
app.use(passport.session());
// GraphQL Setup
// NOTE: request.session.id from inside a function in schema = persistent session
const graphQLHandler = graphqlHTTP(request =>({ graphiql: true, schema }));
app.use('/graphql', graphQLHandler);
// Logout Setup
app.get('/logout', (request, response) => {
// NOTE: request.session.id = non-persistent session
response.send(`user has been logged out`); // someday do request.logout()
});
如您所见,快速会话设置功能(session
)仅被调用一次。我打电话给app.use(passport.session())
(看起来它可能正在创建第二个会话),但我的理解是该行只是告诉Passport使用会话......它不会创建一个完整的单独并行会话。
任何人都可以解释发生了什么,以及如何让我的应用程序共享一个会话?或者,如果有人可以解释我可以在哪里添加一些代码来在创建会话时抛出错误(以便我可以弄清楚我的代码的哪一部分创建了第二个会话),这也很有帮助。
答案 0 :(得分:1)
我找到了答案!显然,我不是唯一遇到此问题的人:https://github.com/jaredhanson/passport/issues/244。你可以在那里阅读所有细节,但是......
TLDR:我的客户端是fetch
- 来自服务器的/logout
。但默认情况下,fetch
并未设置{ credentials: 'same-origin' }
选项,显然您需要提供该选项,否则Passport会默默地开始创建重复会话:(
所以事实证明我的服务器代码没有任何问题,修复只是在客户端执行以下操作:
fetch(`/logout`, { credentials: 'same-origin' });
希望Passport的人们开始抛出错误或警告或者响应这种情况,而不是让他们的穷人在这个令人费解但却很常见的结果中徘徊(答案的评论有15个赞成)