I the past I could just easily add session management using redis as store in express using express-session like so:
import session from "express-session";
module.exports = (config?: {[p: string]: unknown}) => {
server.use(cookieParser());
// etc etc
server.use(session(sessCfg));
server.use('/', router);
return server;
}
This still work when creating a memory store/default store:
import session from "express-session";
import express = require('express');
const server = express();
function sessCfgGenerator() {
return {
"secret": "fdakjlhgafgdsahjkhldg",
"name": "bondinet.sid",
"cookie": {
"httpOnly": true,
"secure": false
},
"resave": false,
"saveUninitialized": true,
"unset": "destroy",
}
}
module.exports = (config?: {[p: string]: unknown}) => {
server.use(cookieParser());
// etc etc
server.use(session(sessCfgGenerator()));
server.use('/', router);
return server;
}
However nowadays to generate a redis store you have to create the client settings and then asynchronous connect to it.
let redisClient = redis.createClient({
socket: {
reconnectStrategy: function (retries: number) {
if (retries > 1000) {
// End reconnecting with built in error
return new Error("Retry time exhausted");
}
// reconnect after
return Math.min((retries + 1) * 100, 60000);
},
}
});
await redisClient.connect();
store = new RedisStore({
client: redisClient,
prefix: prefix,
});
I've tried to include the code into the above loader. To make sure it awaits for redis to start/connect:
import session from "express-session";
import express = require('express');
const server = express();
async generateRedisStore(prefix) {
let redisClient = redis.createClient({
socket: {
reconnectStrategy: function (retries: number) {
if (retries > 1000) {
// End reconnecting with built in error
return new Error("Retry time exhausted");
}
// reconnect after
return Math.min((retries + 1) * 100, 60000);
},
}
});
await redisClient.connect();
return new RedisStore({
client: redisClient,
prefix: prefix,
});
}
async function sessCfgGenerator() {
const opt = {
"secret": "fdakjlhgafgdsahjkhldg",
"name": "bondinet.sid",
"cookie": {
"httpOnly": true,
"secure": false
},
"resave": false,
"saveUninitialized": true,
"unset": "destroy",
store: await generateRedisStore('');
}
}
module.exports = (config?: {[p: string]: unknown}) => {
server.use(cookieParser());
// etc etc
sessCfgGenerator.then(cfg => {
server.use(session(cfg));
console.log("SESSION STARTED");
});
server.use('/', router);
return server;
}
However when I use the asynchronous version I notice that the session management is actually never "available". Even though the line runs (I see clearly the "SESSION STARTED" in the logs), whenever I test a route the session isn't there (below shows "undefined"):
router.get('/test', function(req, res, next) {
const r = 'respond with a test - ' + (req.session ? "loaded" : "undefined");
res.send(r);
});
What is the solution, and how can I make this work? These are actively used libraries so it must be working right?