我有一个使用 Passport 的应用程序,它有一个 GraphQL 端点和一个 /logout
端点。出于某种原因,当我从 GraphQL 端点内部调用 request.isAuthenticated()
时,我返回了 true
,但是当我从 /注销
端点我得到了 false
。
因此,我做了一些日志记录(request.session.id
),结果发现我以某种方式结束了两个 session 。更奇怪的是,我的 GraphQL 端点使用的 session 是持久的:如果我重新启动服务器,它会保持相同的 ID,而 /logout
中的 session 会不断变化。
我认为发生的事情是持久 session 是基于 cookie/DB 的,因此在我的客户端发出第一个请求时恢复,而 /logout
session 不是基于 cookie 的,并且会随服务器重置。我不明白的是为什么我有两个 session !
相关代码如下:
// 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 设置函数 (session
) 仅被调用一次。我确实调用了 app.use(passport.session())
(看起来它可能正在创建第二个 session ),但我的理解是该行只是告诉 Passport 使用 session ......它不会创建一个完整的独立并行 session 。
谁能解释发生了什么,以及如何让我的应用程序共享一个 session ?或者,如果有人可以解释我可以在哪里添加一些代码以在创建 session 时抛出错误(这样我就可以弄清楚我的代码的哪一部分创建了第二个 session ),这也会有所帮助。
最佳答案
我找到答案了!显然我不是唯一遇到这个问题的人:https://github.com/jaredhanson/passport/issues/244 .您可以在那里阅读所有详细信息,但是......
TLDR:我的客户端正在从服务器fetch
-ing /logout
。但是,默认情况下 fetch
不会设置 { credentials: 'same-origin' }
选项,显然您需要提供该选项,否则 Passport 只会默默地开始创建重复 session :(
结果证明我的服务器代码没有任何问题,修复只是在客户端执行以下操作:
fetch(`/logout`, { credentials: 'same-origin' });
希望 Passport 的人开始抛出错误或警告或其他东西来回应这种情况,而不是让他们可怜的用户对莫名其妙但常见的结果感到困惑(带有答案的评论有 15 个赞)。
关于javascript - 我如何拥有两个 Express session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48777201/