sessionredisexpress-session

Multiple sessions created for every request in express.js


The issue I'm describing here it's happening in my local development machine, without any proxy between browser requests and the apps. I have several Node.js microservices which share the same technologies used to manage sessions:

The usual flow sees the user doing login in the authentication app and then being redirected to the frontend (a React app), which performs CORS requests to a backend microservice, which is running a GraphQL server. This issue is very similar to the one described here, even if I have a slightly different configuration (static route just in the auth app and used before session definition and false to both resave and saveUninitialized options).

Both auth/backend apps have this configuration:

const sessionOptions = {
    store: new RedisStore({
        client: redisClient,
        disableTTL: true,
    }),
    secret: "123",
    resave: false,
    saveUninitialized: false,
    proxy: false,
    rolling: true,
    cookie: {
        domain: config.cookie.domain,
        sameSite: config.cookie.sameSite,
        maxAge: toTime(config.cookie.maxAge).ms(),
        secure: config.cookie.secure,
    },
};
app.use(session(sessionOptions));

// Configure passport middleware
app.use(passport.initialize());
app.use(passport.session());

The backend app has the additional CORS config:

app.use(cors({
    origin: "frontend_url",
    credentials: true,
    methods: ['GET', 'POST'],
}));

Initial Redis status:

127.0.0.1:6379> KEYS "*"
(empty list or set)

I go to the login page and a session is created:

127.0.0.1:6379> KEYS "*"
1) "sess:H5VTTBiNSQqu0Fsp2ZfSH2wBZtL4XEZh"

I do log in, the session is still one until I get redirected to my React application and then I get six new sessions:

127.0.0.1:6379> KEYS "*"
1) "sess:NNWse-sp51fVRf6rlnsFpMlZO1gkPgYC"
2) "sess:ofQhH0iBbZOvsJBYMxwHjLL0DKxuFKfS"
3) "sess:XxsTGSoANPE5-fPYbwLmoCgvDho0NTnk"
4) "sess:9wFDQ3_RibJyEXEmJ_8gCxfnak4Uh0yP"
5) "sess:8khC8fgbtO53mJNilMhp88toIcsizxea"
6) "sess:jfQBWogefBr75IgZ5GykSgd5d3t3Mt_D"
7) "sess:H5VTTBiNSQqu0Fsp2ZfSH2wBZtL4XEZh"

Whatever link I click, it raises their number to 16, and so on. I cannot spot any request to my backend which isn't sending the session cookie but OPTION pre-flight requests. So I tried to use my own configuration instead than CORS module, but nothing changed. If I log out, obviously just the original session that matched my session cookie is deleted from Redis, the rest (since I've disabled TTL to have "permanent" sessions) just dangle there. It's also obvious that I don't want Redis to be filled with useless sessions, but I cannot find what could be the real issue. Any advice? Thanks.

UPDATE: I've noticed a different behavior if I try to modify genid function with something customized:

The first request to the auth service raises an exception invalid csrf, because probably it cannot be found inside Redis, since genid is returning null now. The second request (assuming that you use the same email as before and that logging in is successful), leads me to the frontend, and this time I can see just one session being created. Obviously, this isn't a correct flow, but anyway it's strange that it's creating just one session in Redis.


Solution

  • In the end, I discovered some requests sent to my auth service which didn't set the session cookie, for some paths it wasn't even supposed to be used. So I defined those paths related to session with:

    const sessionPaths = ['/path1', '/path2', ...];
    app.use(sessionPaths, session(sessionOptions));
    app.use(sessionPaths, passport.initialize());
    app.use(sessionPaths, passport.session());
    app.use(sessionPaths, csrf());