Using Cookies and Sessions in NestJS

Updated: January 1, 2024 By: Guest Contributor Post a comment

Learn how to manage state between requests in your NestJS application using cookies and sessions, essentials for authentication and user experience personalization.

Getting Started

Cookies are small pieces of data stored on the client-side, which are sent back and forth with each request, thereby enabling session management, tracking, and personalization. Sessions, on the other hand, maintain user data on the server-side, typically identifying the data with a unique session ID stored as a cookie on the client-side. Working with these mechanisms is crucial for stateful interactions in any web application.

Installing necessary packages:

npm install @nestjs/cookies express-session cookie-parser

Using Cookies in NestJS

To use cookies, first, we need to configure the middleware. Import cookieParser in your main.ts:

import * as cookieParser from 'cookie-parser';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(cookieParser());
  // Other middleware
  await app.listen(3000);
}
bootstrap();

Setting and reading cookies in controllers is straight forward:

import { Controller, Get, Req, Res } from '@nestjs/common';
import { Request, Response } from 'express';

@Controller('example')
export class ExampleController {
  @Get('/set-cookie')
  setCookie(@Res() response: Response) {
    response.cookie('test', 'Nest Cookie Value', { httpOnly: true });
    return 'Cookie set';
  }

  @Get('/read-cookie')
  readCookie(@Req() request: Request) {
    const cookie = request.cookies['test'];
    return `Read cookie: ${cookie}`;
  }
}

Using Sessions in NestJS

Setting Up Sessions

To enable sessions, you need to configure express-session. First, set it up in the AppModule‘s imports:

import { Module } from '@nestjs/common';
import * as session from 'express-session';

@Module({
  imports: [
    // other imports...
    session({
      secret: 'my-secret',
      resave: false,
      saveUninitialized: false,
    }),
  ],
})
export class AppModule {}

Using Session in Controllers

With the setup complete, sessions can be handled in a similar manner as cookies:

import { Controller, Get, Session } from '@nestjs/common';

@Controller('sessions')
export class SessionsController {
  @Get('/set')
  setSession(@Session() session: Record<string, any>) {
    session.visits = (session.visits || 0) + 1;
    return session.visits;
  }

  @Get('/get')
  getSession(@Session() session: Record<string, any>) {
    return session.visits;
  }
}

Security is paramount when dealing with sessions. Make sure to use options like ‘httpOnly’, ‘secure’, ‘sameSite’, etc., when setting cookies and choose a store like Redis or a database for production-level session persistence.

Integrating Session Stores

For production, it’s recommended to use a persistent session store. Here’s how to integrate the popular connect-redis store:

import * as session from 'express-session';
import * as Redis from 'ioredis';
import * as connectRedis from 'connect-redis';

const RedisStore = connectRedis(session);
const redisClient = new Redis();

@Module({
  imports: [
    session({
      store: new RedisStore({ client: redisClient }),
      secret: 'secret',
      resave: false,
      saveUninitialized: false,
    }),
    // other imports...
  ],
})
export class AppModule {}

Advanced Usage: Custom Decorators

For better reusability and abstraction, NestJS allows the creation of custom decorators. Here’s how to create a decorator to access the session more effectively:

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const UserSession = createParamDecorator(
  (data: unknown, context: ExecutionContext) => {
    const request = context.switchToHttp().getRequest();
    return request.session;
  },
);

And use it in a controller:

import { Controller, Get } from '@nestjs/common';

@Controller('custom')
export class CustomController {
  @Get('/session')
  getSession(@UserSession() session: Record<string, any>) {
    return session;
  }
}

Summary

This tutorial covered the basics of managing session and cookie data in NestJS, ensuring security measures with proper configuration for a production-ready application, and enhancing codebase modularity with custom decorators. Personalize your app’s state management and leverage these techniques for various user-specific functionalities.