Next.js API返回服务器IP地址而不是客户端IP地址。

huangapple go评论58阅读模式
英文:

Next js api ip address return server ip not client ip

问题

I understand your request. Here's the translated code portion:

我正在使用Next.js应用程序尝试获取客户端用户的IP地址和地理位置但我得到的是我部署在`vercel`服务器上的IP地址

我尝试了中间件
```javascript
import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';

export async function middleware(request: NextRequest, _next: NextFetchEvent) {
    const { nextUrl: url, geo } = request
    const country = geo?.country

    // 克隆请求头并设置新的头部`x-hello-from-middleware1`
    const requestHeaders = new Headers(request.headers)
    requestHeaders.set('country', country || 'EG')
    
    // 你也可以在NextResponse.rewrite中设置请求头
    const response = NextResponse.next({
        request: {
            // 新的请求头
            headers: requestHeaders,
        },
    })
    
    return response
}

然后,在api目录中使用来自头部的country

export default async (req: MyRequest, res: NextApiResponse) => {
   if (req.method === 'GET') {
      const country = req.headers.country;
   }
}

我得到了服务器的国家信息!

我还尝试了:

export default async (req: MyRequest, res: NextApiResponse) => {
   if (req.method === 'GET') {
      const forwarded = req.headers['x-forwarded-for'];
      const ip = typeof forwarded === 'string' ? forwarded.split(/, /)[0] : req.socket.remoteAddress;
   }
}

但结果相同!主机服务器的IP地址。

为什么?有什么解决方法?


<details>
<summary>英文:</summary>

I&#39;m using a Next js application, I&#39;m trying to get the IP address and geolocation of the client user, but I got the id address of the `vercel` server that I deployed on.

I tried `middleware`:

import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';

export async function middleware(request: NextRequest, _next: NextFetchEvent) {
const { nextUrl: url, geo } = request
const country = geo?.country

// Clone the request headers and set a new header `x-hello-from-middleware1`
const requestHeaders = new Headers(request.headers)
requestHeaders.set(&#39;country&#39;, country||&#39;EG&#39;)

// You can also set request headers in NextResponse.rewrite
const response = NextResponse.next({
    request: {
        // New request headers
        headers: requestHeaders,
    },
})

return response

}


then, when using `country` from header in `api` directory:

export default async (req:MyRequest, res:NextApiResponse) => {
if (req.method === 'GET') {
const country= req.headers.country;
}
}

I got server&#39;s country !!

I also tried:

export default async (req:MyRequest, res:NextApiResponse) => {
if (req.method === 'GET') {
const forwarded = req.headers['x-forwarded-for'];
const ip = typeof forwarded === 'string' ? forwarded.split(/, /)[0] : req.socket.remoteAddress;
}
}

But it&#39;s the same result! the ip of the hosting server.

Why?! and what&#39;s the solution?


</details>


# 答案1
**得分**: 1

&gt; 当客户端直接连接到服务器时,客户端的IP地址会发送给服务器(通常会记录在服务器访问日志中)。
&gt; 但是,如果客户端连接经过任何正向或反向代理,服务器只会看到最终代理的IP地址,这通常没有太大用处。
&gt; 如果最终代理是服务器相同安装中的负载均衡器,这一点尤其如此。

我认为问题要么是您正在使用代理,要么是Vercel正在使用负载均衡器。`NextRequest`具有`ip`方法,请尝试使用:

```javascript
const ip = req.ip ?? "127.0.0.1";
英文:

from here

> When a client connects directly to a server, the client's IP address
> is sent to the server (and is often written to server access logs).
> But if a client connection passes through any forward or reverse
> proxies, the server only sees the final proxy's IP address, which is
> often of little use. That's especially true if the final proxy is a
> load balancer which is part of the same installation as the server.

I think the problem is either you are using proxy or vercel is using a load balancer. NextRequest has ip method. try to use

const ip = req.ip ?? &quot;127.0.0.1&quot;;

huangapple
  • 本文由 发表于 2023年6月12日 03:22:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76452178.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定