douyu8187 2014-12-01 18:31
浏览 2344
已采纳

从http.Request获取客户端IP地址的正确方法

What's the correct way to get all client's IP Addresses from http.Request? In PHP there are a lot of variables that I should check. Is it the same on Go?

One that I found is:

req.RemoteAddr

And is the request case sensitive? for example x-forwarded-for is the same as X-Forwarded-For and X-FORWARDED-FOR? (from req.Header.Get("X-FORWARDED-FOR"))

  • 写回答

4条回答 默认 最新

  • douxiongzhen2126 2014-12-01 19:21
    关注

    Looking at http.Request you can find the following member variables:

    // HTTP defines that header names are case-insensitive.
    // The request parser implements this by canonicalizing the
    // name, making the first character and any characters
    // following a hyphen uppercase and the rest lowercase.
    //
    // For client requests certain headers are automatically
    // added and may override values in Header.
    //
    // See the documentation for the Request.Write method.
    Header Header
    
    // RemoteAddr allows HTTP servers and other software to record
    // the network address that sent the request, usually for
    // logging. This field is not filled in by ReadRequest and
    // has no defined format. The HTTP server in this package
    // sets RemoteAddr to an "IP:port" address before invoking a
    // handler.
    // This field is ignored by the HTTP client.
    RemoteAddr string
    

    You can use RemoteAddr to get the remote client's IP address and port (the format is "IP:port"), which is the address of the original requestor or the last proxy (for example a load balancer which lives in front of your server).

    This is all you have for sure.

    Then you can investigate the headers, which are case-insensitive (per documentation above), meaning all of your examples will work and yield the same result:

    req.Header.Get("X-Forwarded-For") // capitalisation
    req.Header.Get("x-forwarded-for") // doesn't
    req.Header.Get("X-FORWARDED-FOR") // matter
    

    This is because internally http.Header.Get will normalise the key for you. (If you want to access header map directly, and not through Get, you would need to use http.CanonicalHeaderKey first.)

    Finally, "X-Forwarded-For" is probably the field you want to take a look at in order to grab more information about client's IP. This greatly depends on the HTTP software used on the remote side though, as client can put anything in there if it wishes to. Also, note the expected format of this field is the comma+space separated list of IP addresses. You will need to parse it a little bit to get a single IP of your choice (probably the first one in the list), for example:

    // Assuming format is as expected
    ips := strings.Split("10.0.0.1, 10.0.0.2, 10.0.0.3", ", ")
    for _, ip := range ips {
        fmt.Println(ip)
    }
    

    will produce:

    10.0.0.1
    10.0.0.2
    10.0.0.3
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛