Securing your Express + TypeScript apps: Using Sessions and Redis

Aashi Singh
4 min readNov 23, 2023

--

Express.js is a powerful web application framework for Node.js, and when building web applications, session management is a crucial aspect. express-session is a middleware that provides session support in Express applications. If you want to enhance the performance and scalability of your session management, using redis as a session store is a great choice.

This blog post will guide you through the process of setting up and using express-session with redis in a Node.js applications written in TypeScript.

Node.js with Redis

Why we need sessions?

Maintaining State Across Requests: HTTP is a stateless protocol, meaning it treats each request from a client to server as independent. Sessions allow developers to maintain state across multiple requests. For example, a shopping cart app needs to remember the items a user has added to their cart as they navigate through different pages.

User Identification and Authentication: Sessions are often used to keep track of user identity across multiple requests. When a user logs into an application, a session can be established to persist their identity throughout their interaction with the application.

Security: Sessions can securely store sensitive user information on the server side. This helps mitigate security risks associated with storing information on the client side, where it might be vulnerable to attacks.

Caching and Performance Optimization: Sessions can be utilized to cache frequently accessed data, reducing the need to fetch or compute it on every request. This can contribute to improved performance and a more responsive user experience.

Prerequisites

Before we begin, make sure you have the following installed:

  1. Node.js and npm — You can download them from https://nodejs.org/.
  2. TypeScript — Install it globally using npm install -g typescript.
  3. An Express.js project initialized with TypeScript. If you haven’t set up an Express.js project with TypeScript, you can create one using the following command: npx tsc --init. This will generate a tsconfig.json file. Make sure to configure it according to your project structure.
  4. Redis server — Ensure that you have a running Redis server. You can download it from https://redis.io/download.

Implementation

Install the necessary packages express-session, ioredis, connect-redis and their types @types/ioredis @types/express-session using npm install -

npm install express-session ioredis connect-redis 
npm install @types/ioredis @types/express-session

In your entry file, import these libraries —

import session from "express-session";
import IORedis from "ioredis";
import RedisStore from "connect-redis";

Redis is an in-memory data structure store that can be used as a caching layer or a persistent key-value database. We will be using the ioredis node library to create a connection using a redis url or you can connect to your local redis instance —

const redisClient = new IORedis(process.env.REDIS_URL || "redis://127.0.0.1:6379");

connect-redis provides a session store for Express applications. Instead of storing session data in the server's memory, it utilizes a Redis database to store session information. Using the redis client connection, create a redis store using the connect-redis library.

const redisStore = new RedisStore({ client: redisClient });

Finally, add the redis store to the session which will be used by the app as the middleware. Provide a secret key which will be used for signing the session ID cookie. This should remain private for security concerns.

We are using httpOnlyCookies to ensure that session cookies cannot be accessed via JavaScript. This is crucial to preventing cookie theft via XSS attacks. Set a maxAge to the cookies so that the session can be expired after some time.

app.use(
session({
store: redisStore,
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: false,
httpOnly: true,
maxAge: 1000 * 60 * 60 * 3,
}
})
)

Using the session object is as easier than just setting a key-value pair in an object. Just add the values like this —

login = async (req: Request, res: Response) => {
// logic for login method goes here...

// store the userId and user's email in the session
req.session.userId = userId;
req.session.email = email;

}

Access the stored data in the session easily using console.log(req.session.userId) and to destroy the session — req.session.destroy

Common issue faced by the users

While setting up express-session and redis in typescript node apps, you might run into errors like —

error using express-session and redis in typescript node apps

This might happen if you have imported connect-redis in your app using import connectRedis from “connect-redis” and then initializing the RedisStore using const RedisStore = connectRedis(session).

import session from "express-session";
import connectRedis from "connect-redis";

const RedisStore = connectRedis(session);

For this to work, instead of initializing the RedisStore in express-session, import it directly from connect-redis. Also, if you were using @types/connect-redis, you can remove that now since types are now included in the main package. These are few of the breaking changes made in the v7 of the connect-redis library. For more information, check out their release announcement here.

Working code snippet —

import session from "express-session";
import IORedis from 'ioredis';
import RedisStore from "connect-redis";

const redisClient = new IORedis(process.env.REDIS_URL || "redis://127.0.0.1:6379");

app.use(
session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: false,
httpOnly: true,
maxAge: 1000 * 60 * 60 * 3,
},
})
)

Congratulations! You’ve successfully set up express-session with ioredis in a Node.js application using TypeScript. This combination allows for efficient and scalable session management in your Express.js web application.

I hope you found this post useful and please do let me know in case of any question or query. Leave a comment here and I will surely reply!

Happy coding!

--

--

Aashi Singh

Full Stack Developer at Salesforce | Creative coder | JavaScript Nerd