前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Go语言获取请求中的IP地址

Go语言获取请求中的IP地址

原创
作者头像
Power
发布于 2025-04-03 08:23:00
发布于 2025-04-03 08:23:00
24100
代码可运行
举报
运行总次数:0
代码可运行

概述

在本文中,我们将使用以下命令获取传入 HTTP 请求的客户端 IP 地址

  • X-REAL-IP标头
  • 如果X-REAL-IP为空,那么我们将回退到X-FORWARDED-FOR标头。
  • 如果X-FORWARDED-FOR为空,那么我们将回退到http.Request 结构的RemoteAddr

请注意

  • X-REAL-IP标头仅包含客户端计算机的一个 IP 地址。某些代理服务器(例如 Nginx)会根据请求之前遇到的信任代理填充此标头(如果为空)。另请注意,此标头很容易被客户端欺骗。
  • X-FORWARDED-FOR  是 IP 地址列表 – 代理链接。将其视为请求跃点日志。因此,如果请求源自 IP 为ip1 的客户端,然后通过ip2的代理服务器,然后经过 IP 为ip3的负载均衡器,则X-FORWARDED-FOR的值将为“ip1,ip2, ip3”因此最好用“,”分隔。另请注意,它也很容易被客户端欺骗。仅当您控制设置标头的代理时才应使用此标头
  • RemoteAddr包含客户端的真实IP地址。它是 Web 服务器从中接收连接并将响应发送到的实际物理 IP 地址。但如果客户端通过代理连接,它将给出代理的 IP 地址。另外,如果您正在使用负载平衡器或反向代理服务器,那么它会给出它们的地址。RemoteAddr代表 IP 端口组合。

在上述 3 个值中,RemoteAddr是最可靠的,但如果客户端位于代理后面或使用负载均衡器或反向代理服务器时,它永远不会给出正确的 IP 地址,因此顺序是先 X-REAL-IP  然后X-FORWARDED-FOR   ,然后是RemoteAddr。但请注意,恶意用户仍然可以创建虚假的X-REAL-IPX-FORWARDED-FOR标头

代码

让我们看一下 GOLANG 实现的代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
    "fmt"
    "net"
    "net/http"
    "strings"
)

func main() {
    handlerFunc := http.HandlerFunc(handleRequest)
    http.Handle("/getIp", handlerFunc)
    http.ListenAndServe(":8080", nil)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
    ip, err := getIP(r)
    if err != nil {
        w.WriteHeader(400)
        w.Write([]byte("No valid ip"))
    }
    w.WriteHeader(200)
    w.Write([]byte(ip))
}

func getIP(r *http.Request) (string, error) {
    //Get IP from the X-REAL-IP header
    ip := r.Header.Get("X-REAL-IP")
    netIP := net.ParseIP(ip)
    if netIP != nil {
        return ip, nil
    }

    //Get IP from X-FORWARDED-FOR header
    ips := r.Header.Get("X-FORWARDED-FOR")
    splitIps := strings.Split(ips, ",")
    for _, ip := range splitIps {
        netIP := net.ParseIP(ip)
        if netIP != nil {
            return ip, nil
        }
    }

    //Get IP from RemoteAddr
    ip, _, err := net.SplitHostPort(r.RemoteAddr)
    if err != nil {
        return "", err
    }
    netIP = net.ParseIP(ip)
    if netIP != nil {
        return ip, nil
    }
    return "", fmt.Errorf("No valid ip found")
}

进行调用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
curl -v -X  GET http://localhost:8080/getIp

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
On my machine it outputs ::1 which is actually loopback address for IPV6

在您的计算机上,它将输出 127.0.0.1(IPV4)或 ::1(IPV6)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验