Tips for creating an HTTP only cookie in NestJS

Currently, I am in the process of incorporating JWT authorization with both an accessToken and refreshToken. The requirement is to store these tokens in HTTP-only cookies.

Despite attempting this code snippet, I have encountered an issue where the cookies are not being set. My project utilizes the NestJS framework.

import { Controller, Request, Post, Body, Response } from '@nestjs/common';
@Controller()
export class UserController {
  constructor() {}

  @Post('users/login')
  async login(
    @Request() req,
    @Body() credentials: { username: string; password: string },
    @Response() res,
  ) {
    try {
      // Login with username and password
      const accessToken = 'something';
      const refreshToken = 'something';
      const user = { username: credentials.username };

      res.cookie('accessToken', accessToken, {
        expires: new Date(new Date().getTime() + 30 * 1000),
        sameSite: 'strict',
        httpOnly: true,
      });
      return res.send(user);
    } catch (error) {
      throw error;
    }
  }
}

The data retrieval using the res.send() method functions as expected, providing the necessary information in the response. However, the challenge lies in setting the cookie itself.

For reference, here is a snippet from my main.ts file:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Logger } from '@nestjs/common';
import { AuthenticatedSocketIoAdapter } from './chat/authchat.adapter';
import * as cookieParser from 'cookie-parser';
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  app.use(cookieParser());
  app.useWebSocketAdapter(new AuthenticatedSocketIoAdapter(app));
  await app.listen(3000);
  Logger.log('User microservice running');
}
bootstrap();

To access the cookie information, I am utilizing the following:

request.cookies

Answer №1

Discussion within the comments:

To ensure that Axios on the user's end communicates effectively with the server, it is crucial to have the withCredentials parameter set to true, allowing for proper cookie exchange between the two. Fortunately, the server was successfully sending and configuring the cookies as required.

Answer №2

I encountered a similar issue recently where Axios was unable to save cookies properly. To fix this, I had to set up SameSite: 'none' and secure: true in Chrome. However, even after making these changes, the issue persisted as the cookie was only saved when using the fetch method in browsers running on Chromium, not Mozilla. The Axios code I used was:

const response = await axios.post(url+'/login', loginState, {withCredentials: true});

In my Nestjs backend Main.ts file, I defined the app setup as follows:

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.setGlobalPrefix('v1/api');
  app.use(cookieParser());
  app.useGlobalPipes(new ValidationPipe());
  app.enableCors({
    credentials: true,
    origin: process.env.FRONTEND_URL,
  })
  await app.listen(3000);
}

Within my AuthService Login function, I included passthrought: true in the Response:

@Post('login')
async login(
        @Body()body: LoginUserDTO,
        @Res({passthrough: true}) response: Response
    ): Promise<any> {
    // Authentication logic here
    response.cookie('jwt', jwtToken, {httpOnly: true, domain: frontendDomain,});

    return {'jwt': jwtToken}
}

The issue was resolved by adding the domain to the response.cookie command. My development environment variables for CORS and cookie domain were:

FRONTEND_URL = http://localhost:3333
FRONTEND_DOMAIN = localhost

I hope this information proves helpful to you.

Answer №3

If you're interested in setting http-only cookies, you have a couple of options depending on the engine (fastify, express) you are using:

async updateCookies(@Res({ passthrough: true }) res: FastifyReply): Promise<void> {
    const [cookieName, cookieToken] = ['sessionCookie', 'superSecretToken'];
    
    // 1. Utilizing a specific method tailored to the engine
    res.setCookie(cookieName, cookieToken, { httpOnly: true, maxAge: 60_000 });

    // 2. Standard approach
    res.header('Set-Cookie', [`${cookieName}=${cookieToken}; HttpOnly; Secure; SameSite=Strict; Max-Age=60; Path=/;`, 'additionalCookiesAndSettings...']);
}

For more insights, refer to MDN's documentation

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

After updating the file path, the Next.Js module couldn't be located: Module not found – Unable to

After relocating the EmptyTable.tsx file from its original directory at views/forms-tables/tables/react-table/EmptyTable to a new location at components/Tables/EmptyTable, I encountered a persistent issue. Despite updating the import path in my code to mat ...

Issue: Catching errors in proxy function calls

I am currently using Vue 3 along with the latest Quasar Framework. To simplify my API calls, I created an Api class as a wrapper for Axios with various methods such as get, post, etc. Now, I need to intercept these method calls. In order to achieve this ...

Revamping an npm package on GitHub

Currently, I am managing a project that has gained popularity among users and has received contributions from multiple individuals. The next step I want to take is to convert the entire library into TypeScript, but I am unsure of the best approach to ach ...

Using EJS Variables within HTML Style Tags

I'm currently facing an issue trying to include a variable in the style attribute of this div: <div class="progress progress-sm"> <div class="progress-bar bg-success" aria-valuenow="<%=Math.round((resp.length ...

Ensuring Compliance with GDPR through Cookie Consent Logic

Since the introduction of GDPR, I find myself in need of clarity on the steps to take both server-side and client-side to ensure compliance. Apologies for the plethora of questions. I currently have a first-party cookie that is used to store a session coo ...

Storing blank information into a Mongodb database with Node.js and HTML

Can someone please assist me with solving this problem? const express=require("express"); const app=express(); const bodyparser=require("body-parser"); const cors=require("cors"); const mongoose=require("mongoose"); ...

Identify the individual who accessed a hyperlink within an email

My team is planning a small experiment involving sending an email to around 50 employees. The email will contain a link to a website stored on our local server, and I want to be able to track exactly who clicks the link by matching it with their email addr ...

Is it possible to link Cookies with Homescreened HTML5 Applications?

It seems that when an HTML5 app is added to the homescreen on iOS, it loses the ability to work with cookies. My setup involves a node.js server running connect. I've come across solutions like that address this issue for other platforms. Is there ...

IISNode is presenting a consistent outcome for a GET request with query parameters, which was not anticipated

I have an express.js application running on IIS with IISNode and URL Rewrite rules following best practices. There is a specific endpoint /foo?q=1 that generates a unique HTML body with each GET request, displaying a dynamic timestamp. However, after the ...

What is the best way to implement an Angular Guard that utilizes an API service for validation and redirects in case of failure?

Hello there! I am currently working on an Angular 7 application that deals with time cards. One of the main features I have implemented is a CanActivate Guard for controlling access to certain components. The CanActivate code utilizes Observables to decid ...

Understanding the infer keyword in Typescript when working with generic type constraints

Exploring a scenario where I have a generic interface that requires a type argument extending another generic type. export interface IPoint<TX, TY> { x: TX; y: TY; } export interface ISeries<TPoint extends IPoint> { points: Array& ...

Encountering Build Issue: "NgSemanticModule is not recognized as an NgModule" persists despite inclusion of dependencies and importing into primary module

I have posted my module, component, and package file here. I am attempting to implement a click event with ngif, but I keep encountering an error. The specific error message is "ERROR in NgSemanticModule is not an NgModule". I'm unsure if this error ...

Acquire information from the user interface and display it in a highcharts chart using Angular 5

Currently, I am utilizing an npm package for chart creation, which can be found at the following link: https://www.npmjs.com/package/angular-highcharts I have a specific interface set up and I aim to extract values from this interface to populate a line g ...

Communicate with MongoDB using Express

Currently, I am facing an issue while trying to establish a connection between my application and MongoDB using Express. The collection 'users' is functioning perfectly without any troubles, but the same cannot be said for my second collection. W ...

To enhance VS IntelliSense and type checking in react-intl's FormattedMessage component, assign an id that aligns with a custom TypeScript interface

Due to the limitations of react-localization in terms of date and number formats, as well as its heavy reliance on a single developer, our team made the decision to transition to react-intl for a more stable long-term solution. Check out the contributors ...

Following the update, Angular no longer requires any node dependencies

Recently upgraded from Angular 5 to 9 and encountered an error in the browser's devtools: Uncaught ReferenceError: global is not defined After researching, I found a helpful post that discusses the issue: Upgrading to angular-6.x gives "Unca ...

The combination of both fullWidth and className attributes on a Material-UI component

I am facing an issue with using both the className and fullWidth properties on a Material UI TextField component. It seems that when trying to apply both, only the className is being recognized. When I use just the className or just the fullWidth property ...

Navigating through ionic2 with angularjs2 using for-each loops

I developed an application using IONIC-2 Beta version and I am interested in incorporating a for-each loop. Can anyone advise if it is possible to use for each in Angular-V2? Thank you. ...

Troubleshooting problem with refreshing URL on "ionic serve" mode

After transitioning my project from Ionic 2 to Ionic 3, I've encountered an issue with ionic serve and the rebuilding process. Initially, when I build the project, everything functions as expected. However, I've noticed that the URL in the brows ...

Unable to assign to 'disabled' as it is not recognized as a valid attribute for 'app-button'

How to link the disabled property with my button component? I attempted to add 'disabled' to the HTML file where it should be recognized as an input in the button component (similar to how color and font color are recognized as inputs) ... but ...