expresscookiespassport.jsexpress-sessionpassport-local

Cookie issues with Passport: why are cookies not sent/stored?


I'm struggling while implementing authentication in my Express application using Passport.js.

First of all here are all my packages' versions and my config:

"passport": "^0.7.0",
"passport-local": "^1.0.0",
"express": "^4.18.2",
"express-session": "^1.18.1",
"redis": "^4.6.10",
"connect-redis": "^8.0.1",
"cookie-parser": "^1.4.7",

I'm using Passport on Express with the local strategy and Redis as the storage.

The issues:

  1. I noticed that after successful authentication, the cookies were not being sent to the client.
  2. In some cases, even when the cookies appeared to be set, they were not being stored properly in the browser.

Questions:

  1. Has anyone else encountered similar issues with cookies while using Passport with Express?
  2. What are some common pitfalls or configurations that could lead to cookies not being sent or stored?

Solution

  • So here are all the issues I encountered:

    Session not stored in Redis

    When I was trying to log in to my app, strangely, the sessions never appeared in Redis. The initialization of my redisClient was done after the definition of redisStore.

    So, be careful with your imports and make sure that your definitions are called in the correct order.

    req.cookies['connect.sid'] is undefined

    Simply put, your cookieParser middleware is not set up. I thought that cookieParser was included in express-session, but to use it in your code, you must set it up yourself with a simple app.use(cookieParser('keyboard cat'));

    Cookie sent in local but not in prod/test

    Here, it was my nginx configuration's fault. My backend was running on an AWS EC2 instance, and this header was missing in my proxy-pass configuration:

    proxy_set_header X-Forwarded-Proto $scheme;

    Without it, my browser was unable to set my cookie.

    Chrome issue with the cookies

    As you know, Chrome enforces strict rules for cookies, so it might reject your cookies. My way of dealing with this was to use a self-signed SSL certificate. To do this, I created this little package:

    https://www.npmjs.com/package/local-ssl-certifier

    It will generate self-signed SSL certificates and keys, and there are examples of how to use it with Angular and Express.

    My Express session configuration

    Here is my Express session initialization:

    app.use(
        session({
            secret: 'keyboard cat',
            resave: false,
            saveUninitialized: false,
            cookie: {
                secure: true,
                maxAge: 60 * 60 * 4 * 1000,
                httpOnly: true,
                domain: '',
                sameSite: env.SAME_SITE,
            },
            store: redisStore,
        }),
    );
    

    The value of env.SAME_SITE for me is none when I'm on localhost and lax when my app is running on an EC2 instance.

    Additional warnings


    I hope this post will help some of you!