Как мне провести две экспресс-сессии?

У меня есть приложение, использующее Passport с конечной точкой GraphQL и конечной точкой /logout. По какой-то причине, когда я вызывал request.isAuthenticated() из конечной точки GraphQL, я вернулся true, но когда я сделал тот же самый точный вызов из конечной точки /logout, я вернулся false.

Итак, я немного записал (request.session.id), и оказалось, что я как-то закончил с двумя сеансами. Еще страннее, сеанс, используемый моей конечной точкой GraphQL, является постоянным: если я перезапускаю сервер, он сохраняет один и тот же идентификатор, а тот, который находится в /logout, продолжает меняться.

Я думаю, что происходит то, что постоянный сеанс является файлом cookie/DB и поэтому восстанавливается, когда мой клиент делает свой первый запрос, а сеанс /logout не основан на cookie и получает reset с сервер. Я не понимаю, почему у меня две сессии!

Вот соответствующий код:

// 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 использовать сеанс... он не создает целую отдельную параллельную сессию.

Может ли кто-нибудь объяснить, что происходит, и как я могу подключить мое приложение к одному сеансу? Или в качестве альтернативы, если кто-нибудь может объяснить, где я мог бы добавить код, чтобы вызывать ошибку всякий раз, когда создается сеанс (чтобы я мог выяснить, какая часть моего кода создает второй сеанс), что тоже было бы полезно.

1 ответ

Я нашел ответ! По-видимому, я был не единственным, у кого была эта проблема: https://github.com/jaredhanson/passport/issues/244. Вы можете прочитать все подробности там, но...

TL;DR: Мой клиент был fetch -ing /logout с сервера. Однако по умолчанию fetch не устанавливает параметр { credentials: 'same-origin' }, и, по-видимому, вам необходимо предоставить это, иначе Паспорт просто начинает создавать повторяющиеся сеансы: (

Итак, оказалось, что ничего не случилось с моим кодом сервера, исправление просто делало следующее на стороне клиента:

fetch(`/logout`, { credentials: 'same-origin' });

Здесь надеются, что люди Паспорта начнут бросать ошибки или предупреждения или что-то в ответ на этот случай, вместо того, чтобы позволить своим бедным пользователям бояться по необъяснимому, но общему результату (комментарий с ответом имел 15 палец вверх).

licensed under cc by-sa 3.0 with attribution.