Sling Academy
Home/Node.js/Using Cookies and Sessions in NestJS

Using Cookies and Sessions in NestJS

Last updated: January 01, 2024

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.

Next Article: NestJS & TypeORM Import Error: ‘Cannot use import statement outside a module’

Previous Article: How to Monitor and Log Errors in NestJS

Series: Nest.js Tutorials: From Basics to Advanced

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates