如何在使用Node和Nest.js分离客户端和服务器应用程序时获取用户的IP地址

6
我有两个应用程序,一个是前端(react.js),另一个是REST API后端(基于express.js的nest.js)。当前端客户端向后端发出请求时,我该如何获取访问后端的用户IP地址?
我查看了这个问题并尝试了解决方案 在使用Koa的Node中,如何获取独立的客户端和服务器应用程序中的用户IP地址? Express.js:如何获取远程客户端地址 但是我得到的是前端服务器的IP而不是客户端IP。
在没有更改前端应用程序的情况下,有没有一种方法可以在nest.js中获取真正的客户端IP?
6个回答

16
根据 NestJS 文档,有一个可用的装饰器来获取请求的 IP 地址。它的用法如下所示:

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

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

以下是可用的装饰器的完整列表: https://docs.nestjs.com/custom-decorators


未生效。我得到的IP是:::ffff:127.0.0.1 - Henry
2
如果你正在本地主机上工作,那就是你会得到的回应,@Henry。 - Manuel Duarte

4

您可以从一个 Request 对象中提取出IP地址

我将其作为中间件使用,以在日志条目中打印用户的IP地址,以下是我的操作方法:

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();
    }
}

3

您可以安装一个名为request-ip的库:

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

main.ts文件中,在您的应用程序中注入请求IP中间件:
app.use(requestIp.mw());

现在你可以从请求对象中访问客户端IP:

req.clientIp

另一种方法是定义一个装饰器:

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);
});

你可以在控制器中使用装饰器:

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

请查看github上的这个问题


对我来说,req 的类型是 ExecutionContext。因此,不要称其为 req,而应该称其为 ctx,并执行以下操作: const request = ctx.switchToHttp().getRequest(); - Crazy Redd
1
request-ip 已经有大约三年没有得到适当的维护了。它选择的头部 IP 地址可以被伪造。 - Dan

0
我从 @Request() req 的 headers 中获取 IP。
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

-1
这对我有用:
  @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]
      ...
  }

-2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接