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

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

Next js api ip address return server ip not client ip

问题

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

  1. 我正在使用Next.js应用程序尝试获取客户端用户的IP地址和地理位置但我得到的是我部署在`vercel`服务器上的IP地址
  2. 我尝试了中间件
  3. ```javascript
  4. import { NextFetchEvent, NextRequest, NextResponse } from 'next/server';
  5. export async function middleware(request: NextRequest, _next: NextFetchEvent) {
  6. const { nextUrl: url, geo } = request
  7. const country = geo?.country
  8. // 克隆请求头并设置新的头部`x-hello-from-middleware1`
  9. const requestHeaders = new Headers(request.headers)
  10. requestHeaders.set('country', country || 'EG')
  11. // 你也可以在NextResponse.rewrite中设置请求头
  12. const response = NextResponse.next({
  13. request: {
  14. // 新的请求头
  15. headers: requestHeaders,
  16. },
  17. })
  18. return response
  19. }

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

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

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

我还尝试了:

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

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

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

  1. <details>
  2. <summary>英文:</summary>
  3. 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.
  4. 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

  1. // Clone the request headers and set a new header `x-hello-from-middleware1`
  2. const requestHeaders = new Headers(request.headers)
  3. requestHeaders.set(&#39;country&#39;, country||&#39;EG&#39;)
  4. // You can also set request headers in NextResponse.rewrite
  5. const response = NextResponse.next({
  6. request: {
  7. // New request headers
  8. headers: requestHeaders,
  9. },
  10. })
  11. return response

}

  1. 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;
}
}

  1. I got server&#39;s country !!
  2. 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;
}
}

  1. But it&#39;s the same result! the ip of the hosting server.
  2. Why?! and what&#39;s the solution?
  3. </details>
  4. # 答案1
  5. **得分**: 1
  6. &gt; 当客户端直接连接到服务器时,客户端的IP地址会发送给服务器(通常会记录在服务器访问日志中)。
  7. &gt; 但是,如果客户端连接经过任何正向或反向代理,服务器只会看到最终代理的IP地址,这通常没有太大用处。
  8. &gt; 如果最终代理是服务器相同安装中的负载均衡器,这一点尤其如此。
  9. 我认为问题要么是您正在使用代理,要么是Vercel正在使用负载均衡器。`NextRequest`具有`ip`方法,请尝试使用:
  10. ```javascript
  11. 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

  1. 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:

确定