Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I set a header field in a response with NestJS?

I'm trying:

    @Post('login')
    async login(@Body() body: AuthDto, @Res() res: Response) {
        const loginResponse = await this.authService.login(body);
        console.log('loginResponse', loginResponse)
        res.headers.set('x-access-token', loginResponse.access_token)
        return loginResponse
    }

but no dice. I get an error:

TypeError: Cannot read property 'set' of undefined
like image 898
Shamoon Avatar asked May 09 '20 13:05

Shamoon


People also ask

How do I set response headers in Nestjs?

To specify a custom response header, you can either use a @Header() decorator or a library-specific response object (and call res. header() directly). Hint Import Header from the @nestjs/common package.

How do you set a response header?

Select the web site where you want to add the custom HTTP response header. In the web site pane, double-click HTTP Response Headers in the IIS section. In the actions pane, select Add. In the Name box, type the custom HTTP header name.

Can we change response header?

You can add a new header or remove, modify an existing request/response header. For this example, we will select Remove. Add operation works when a new header is to be added to the request/response whereas modify option modifies an already existing header.

How do I get the response header value?

The getResponseHeader() method returns the value as a UTF byte sequence. Note: The search for the header name is case-insensitive. If you need to get the raw string of all of the headers, use the getAllResponseHeaders() method, which returns the entire raw header string.


3 Answers

Not the most elegant way: return res.set({ 'x-access-token': loginResponse.access_token }).json(loginResponse);

I'd separate this logic into an interceptor, checking if the response is valid for path /login, if so return the correct header (using some value from loginResponse)

import { Controller, Get, Response } from '@nestjs/common';
import { Response as Res } from 'express';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(@Response() res: Res): Res {
    return res.set({ 'x-access-token': 1 }).json({ hello: 'world' });
  }

  @Get()
  getHelloAlt(@Response() res) {
    return res.set({ 'x-access-token': 1 }).json({ hello: 'world' });
  }
}

This is my working version, notice the Express Response and not Nest.js.

EDIT: The type imported from Nest.js/common is a decorator function, instead either use no type, or import Response from Express.js.

like image 142
Isolated Avatar answered Nov 11 '22 08:11

Isolated


To specify a custom response header, you can either use a @Header() decorator or a library-specific response object (and call res.header() directly).

Import Header from the @nestjs/common package.

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}
like image 36
Ismail Avatar answered Nov 11 '22 08:11

Ismail


I use an interceptor. As I want to add a field to the headers on the response indicating my service, I also set this as a global interceptor, but you can use it by route as well.

response-add-access-token-to-header.interceptor.ts

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';

import { Response as ExpressResponse } from 'express';

@Injectable()
export class ResponseAddAccessTokenToHeaderInterceptor implements NestInterceptor {
    intercept(context:ExecutionContext, next:CallHandler): Observable<any> {

        const ResponseObj:ExpressResponse = context.switchToHttp().getResponse();
        ResponseObj.setHeader('x-access-token', 'Your Data' );
        return next.handle();
    }
}

To add it globally, adjust main.ts:

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    app.useGlobalInterceptors(new ResponseAddAccessTokenToHeaderInterceptor());
    await app.listen(8080);
}
bootstrap();
like image 38
Steven Scott Avatar answered Nov 11 '22 08:11

Steven Scott