Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@nestjsplus/cookies

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nestjsplus/cookies

Decorators for Managing Cookies with NestJS

  • 1.1.1
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
513
increased by7.32%
Maintainers
1
Weekly downloads
 
Created
Source

Nest Logo

Decorators for Managing Cookies with NestJS

License npm version Built with NestJS

Version Compatibility - Nest v7

For the time being at least (until I can invest more time in this), Nest v7 will be supported in the @nestjsplus/cookies@1.1.x code line (sorry if that's not correct SEMVER; what I mean is version 1.1.x is built on Nest 7). Nest 6 will be supported on the 1.0.x version line.

The incompatibility is due to a change in Nest's createParamDecorator() function, and at the moment I haven't tried to figure out how to maintain compatibility across the two.

Please file an issue if you have difficulties with v1.1.x and Nest v7.

Installation

npm install @nestjsplus/cookies

Motivation

NestJS doesn't currently have decorators for getting and setting cookies. While it's not too hard to read cookies, it's convenient to have a parameter decorator to do so.

@Post('login')
login(@Cookies() cookies) {
  console.log('Got cookies:', cookies);
}

Setting cookies is a little less straightforward. You either need to utilize the platform-specific response (res) object, or write an interceptor. The former is pretty straightforward, though takes a non-Nest-like imperative style. It also puts you into manual response mode, meaning you can no longer rely on features like @Render(), @HttpCode() or interceptors that modify the response, and makes testing harder (you'll have to mock the response object, etc.). The @SetCookies() decorator from this package wraps an interceptor in a declarative decorator that solves these issues.

Collectively, the @Cookies(), @SignedCookies(), @SetCookies() and @ClearCookies() decorators in this package provide a convenient set of features that make it easier to manage cookies in a standard and declarative way, and minimize boilerplate code.

See Also

If you like these decorators, you may also be interested in the NestJS Redirect decorator.

Importing the Decorators

Import the decorators, just as you would other Nest decorators, in the controllers that use them as shown below:

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
import { Cookies, SignedCookies } from '@nestjsplus/cookies';

@Controller()
export class AppController {
...

Reading Cookies

Reading cookies requires the cookie-parser package to be installed. See here for details. Reading signed cookies requires that the CookieParser be configured with a signing secret.

Regular (non-signed) Cookies

Use the @Cookies() route parameter decorator to get "regular" cookies.

@Get('get')
get(@Cookies() cookies): string {
  console.log('cookies: ', cookies);
  return this.appService.getHello();
}

This will bind an array of all (non-signed) cookies to the cookies parameter. See below to access a named cookie.

Signed Cookies

Use the @SignedCookies() route parameter decorator to get signed cookies.

@Get('getSigned')
getSigned(@SignedCookies() cookies) {
  console.log('signed cookies: ', cookies);
}

As with @Cookies(), this will bind an array of all signed cookies to the cookies parameter. Access individual signed cookies as described below.

Accessing Specific (Named) Cookies

Pass the name of a specific cookie in the @Cookies() or @SignedCookies() decorator to access a specific cookie:

get(@SignedCookies('cookie1') cookie1) { ... }

Setting Cookies

Use the @SetCookies() route handler method decorator to set cookies.

Here's the API:

@SetCookies(
  options?: CookieOptions,
  cookies?: CookieSettings | CookieSettings[]
)

Here's how it works. You have two options, depending on whether the cookie settings are static or dynamic.

  1. For static cookies, where the cookie name and/or value are known at compile time, you can set them in the @SetCookies() decorator by passing a CookieSettings object.

    <br/>For example:
    
@SetCookies({name: 'cookie1', value: 'cookie 1 value'})
@Get('set')
set() {
  ...
}
  1. For dynamic cookies, where the cookie name and/or value are computed at run-time, you can provide the cookie name/value pairs to be set when the route handler method runs. Provide these values by passing them on the req._cookies array property. (The decorator creates the _cookies property automatically for you). Note: Of course if you are using this technique, you are de facto accessing the request object, so you must bind @Request() to a route parameter.

    <br/>For example:
    
set(@Request() req) {
  const cookie1Value = 'chocoloate chip';
  req._cookies = [
    {
      name: 'cookie1',
      value: cookie1Value,
      options: {
        signed: true,
        sameSite: true,
      },
    },
    { name: 'cookie2', value: 'oatmeal raisin' },
  ];
  ...
Defaults and overriding

You can mix and match CookieOptions and CookieSettings in the decorator and in the method body as needed. This example shows dynamic cookies with defaults inherited from the decorator, and overrides in the body:

@SetCookies({httpOnly: true},
 [
   {name: 'cookie1', value: 'cookie 1 value'},
   {name: 'cookie2', value: 'cookie 2 value', {httpOnly: false}}
 ]
)

As a result of the above, cookie1 will be set as HttpOnly, but cookie2 will not.

  • Set default cookie options by passing a CookieOptions object in the decorator. Options set on individual cookies, if provided, override these defaults.

As shown above, each cookie you set has the shape:

interface CookieSettings {
  /**
   * name of the cookie.
   */
  name: string;
  /**
   * value of the cookie.
   */
  value?: string;
  /**
   * cookie options.
   */
  options?: CookieOptions;
}

If options are provided for a cookie, they completely replace any options specified in the @SetCookies() decorator. If omitted for a cookie, they default to options specified on the @SetCookies() decorator, or Express's default cookie settings if none were set.

CookieOptions

Cookie options may be set at the method level (@SetCookies()), providing a set of defaults, or for individual cookies. In either case, they have the following shape:

interface CookieOptions {
  /**
   * Domain name for the cookie.
   */
  domain?: string;
  /**
   * 	A synchronous function used for cookie value encoding. Defaults to encodeURIComponent.
   */
  encode?: (val: string) => string;
  /**
   * Expiry date of the cookie in GMT. If not specified or set to 0, creates a session cookie.
   */
  expires?: Date;
  /**
   * Flags the cookie to be accessible only by the web server.
   */
  httpOnly?: boolean;
  /**
   * Convenient option for setting the expiry time relative to the current time in milliseconds.
   */
  maxAge?: number;
  /**
   * Path for the cookie. Defaults to “/”.
   */
  path?: string;
  /**
   * Marks the cookie to be used with HTTPS only.
   */
  secure?: boolean;
  /**
   * Indicates if the cookie should be signed.
   */
  signed?: boolean;
  /**
   * Value of the “SameSite” Set-Cookie attribute. More information at
   * https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1.
   */
  sameSite?: boolean | string;
}
Route Handler Results and Behavior

The route handler otherwise proceeds as normal. It can return values, and it can use other route handler method decorators (such as @Render()) and other route parameter decorators (such as @Headers(), @Query()).

Example

Setting cookies isn't hard! See a full example here in the test folder.

Clearing (deleting) Cookies

Delete cookies in one of two ways:

  1. Use @SetCookies() and pass in only the cookie name (leave the value property off of the object).
  2. Use @ClearCookies(), passing in a comma separated list of cookies to clear.
@ClearCookies('cookie1', 'cookie2')
@Get('kill')
@Render('clear')
kill() {
  return { message: 'cookies killed!' };
}

Restrictions

Express Only

These decorators currently only work with Nest applications running on @platform-express. Fastify support is not currently available.

Note that reading cookies depends on the standard Express cookie-parser package. Be sure to install it and configure it in your app. For example:

npm install cookie-parser

and in your main.ts file:

import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';

import * as CookieParser from 'cookie-parser';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  app.use(CookieParser('secret'));

  await app.listen(3000);
}
bootstrap();
Decorators Can't Access this

Note that decorators have access to the class (Controller), but not the instance. This means that, for example, if you want to pass a variable to a SetCookies() decorator, you should pass a variable set in the outer scope of the file (e.g., a const above the controller class definition), as opposed to a property on the controller class.

See the controller in the test folder for an example.

Change Log

See Changelog for more information.

Contributing

Contributions welcome! See Contributing.

Author

  • John Biundo (Y Prospect on Discord)

License

Licensed under the MIT License - see the LICENSE file for details.

Keywords

FAQs

Package last updated on 28 Mar 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc