7

My question is similar to the following: How do I get the domain originating the request in express.js? but I'm using NestJS. I found that there might be a good answer for express.js, but I cannot apply it on NestJS (req.origin is undefined).

Could anyone help me with this? Thank you in advance.

Nathalie
  • 821
  • 2
  • 8
  • 14

6 Answers6

5

In my project below code is worked.

async login (@Headers() headers) {
  console.log('AUTHH LOGG', headers.host)
}
ahmet üzgör
  • 47
  • 1
  • 2
3

If running @Headers() like this...

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

@Get()
findAll(@Headers() headers: Headers) {
  console.log(headers);
}

it gives you

{
  "host": "localhost:3001",
  "connection": "keep-alive",
  "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"100\"",
  "accept": "application/json, text/plain, */*",
  "sec-ch-ua-mobile": "?0",
  "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) OtherShtuff",
  "sec-ch-ua-platform": "\"Windows\"",
  "origin": "http://localhost:3000",
  "sec-fetch-site": "same-site",
  "sec-fetch-mode": "cors",
  "sec-fetch-dest": "empty",
  "referer": "http://localhost:3000/",
  "accept-encoding": "gzip, deflate, br",
  "accept-language": "en-US,en;q=0.9,fr;q=0.8,es;q=0.7,de;q=0.6",
  "cookie": "_ga=GA1blahblahblah"
}

so to get the actual host origin as asked, using the below works. However, using @Headers() headers: Header then calling headers.origin causes typescript errors since Headers doesn't define all the parameters above. So you'd have to define it yourself, so I would stick to one of the two options below.

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

@Get()
findAgain(@Headers('origin') origin: string) {
  console.log(origin);
}

// or 

@Get()
findEvenMore(@Request() req: Request) {
  console.log(req.get("origin"));
  console.log(req.headers.origin);
}
wongz
  • 3,255
  • 2
  • 28
  • 55
2

from docs, you can have access to request object in Nestjs.

Nest provides access to the request object of the underlying platform (Express by default). We can access the request object by instructing Nest to inject it by adding the @Req() decorator to the handler's signature.

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}
Moazzam Arif
  • 298
  • 1
  • 5
0

In the controller use the @Req() decorator to access the request object and req.get('origin') will give you the domain from which the request originated

    @Get()
    async testAPIKey(@Req() req, @Headers() headers) {
       const origin = req.get('origin');
       console.log(origin) // This will return the origin.
    }
Josejacob99
  • 415
  • 1
  • 4
  • 9
0

It depends on where you want to have it. Besides from the all answers bellow, you can also extract from Request object in custom guard/interceptor by:

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class Your_Custom_Guard_Name_Class implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    // Headers object contains all what you need
    const { host } = context.switchToHttp().getRequest().headers; 
      // Your code
    } 
  }
}

And use it in your controller like:

@UseGuards(Your_Custom_Guard_Name_Class)
@Post('endpointWithCustomGuard')
async login() {
  ...
}
Elmatsidis Paul
  • 385
  • 1
  • 7
  • 19
-1

I found the answer for my question, we can use @Host('origin'). The value exists only when we call the back-end server from a real front-end, not from Postman or directly call back-end url from browser. Thank you Moazzam Arif for helping, allow use your example to show my answer below.

@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Host('origin') origin: string): string {
    return 'This action returns all cats';
  }
}
Nathalie
  • 821
  • 2
  • 8
  • 14