5

I have two apps, one front end (react.js) and one a REST API back-end(nest.js based on express.js). How do I get the IP address of the user accessing the back-end when the front-end client makes a request to the back-end?

I checked this question and try the solutions

With separate client and server apps, how do I get a user's IP address, in Node with Koa?

Express.js: how to get remote client address

but I get server IP of front-end not client IP.

Is there a way without any change in front-end app, I get real client IP in nest.js?

Mohammad Yaser Ahmadi
  • 4,664
  • 3
  • 17
  • 39

6 Answers6

13

According to the NestJS docs, there's a decorator available to get the request Ip Address. It's used like this:

import {Get, Ip} from "@nestjs/common"

@Get('myEndpoint')
async myEndpointFunc(@Ip() ip){
  console.log(ip)
}

Here's a complete list of decorators that can be used: https://docs.nestjs.com/custom-decorators

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Manuel Duarte
  • 644
  • 4
  • 18
4

You can extract IP address from a Request object.

I am using it as a middleware to print user's IP address in a log entry, here is how I do that:

import { Injectable, Logger, NestMiddleware } from "@nestjs/common";
import { NextFunction, Request, Response } from "express";

@Injectable()
export class HttpLoggerMiddleware implements NestMiddleware {
    private logger = new Logger();

    use(request: Request, response: Response, next: NextFunction): void {
        const { ip, method, originalUrl } = request;

        response.on("finish", () => {
            const msg = `${ip} ${method} ${originalUrl}`;
            this.logger.log(msg);
        });

        next();
    }
}
rand0rn
  • 678
  • 2
  • 12
  • 29
3

You may install a library called request-ip:

npm i --save request-ip
npm i --save-dev @types/request-ip

In main.ts file inject request-ip middleware within your app:

app.use(requestIp.mw());

Now you can access clientIp from request object:

req.clientIp

Another way is by defining a decorator:

import { createParamDecorator } from '@nestjs/common';
import * as requestIp from 'request-ip';

export const IpAddress = createParamDecorator((data, req) => {
    if (req.clientIp) return req.clientIp;
    return requestIp.getClientIp(req);
});

And you can use the decorator in controller:

@Get('/users')
async users(@IpAddress() ipAddress){
}

Check the following issue in github.

ikoujar
  • 214
  • 1
  • 6
  • For me, req was of type ExecutionContext. So instead of calling it req, call it ctx and do: `const request = ctx.switchToHttp().getRequest();` – Crazy Redd Jan 26 '22 at 01:50
  • 1
    `request-ip` hasn't been properly maintained for ~3 years now. The IP address it picks for header can be forged. – Dan Feb 28 '22 at 21:24
0

I get the IP from headers in @Request() req:

const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
Henry
  • 1,077
  • 1
  • 16
  • 41
0

This works for me:

  @Post("/mypath")
  @HttpCode(HttpStatus.OK)
  async intention(
      @Body() body: MyRequest,
      @Req() requestToReadIp: Request
  ): Promise<PurchaseIntentionResponse>  {
      const ips = requestToReadIp.headers['x-forwarded-for'] as string
      const userIp = ips.split(",")[0]
      ...
  }
-1

If you are fine using 3rd-party library. You can check request-ip

https://github.com/pbojinov/request-ip

Mike Gerard
  • 141
  • 2
  • 9