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:
Questions:
So here are all the issues I encountered:
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.
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'));
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.
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.
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.
credentials: true
in your CORS settings.app.use(passport.initialize());
is called before app.use(passport.session());
.I hope this post will help some of you!