Gin允许您指定保存真实客户端IP的头文件(如果有的话),以及指定您信任的代理(或直接客户端)来指定这些头文件之一。
在gin.engine上使用函数setTrustedProxies(),以指定网络地址或网络CIDR,客户端的请求体头包含与之相关的IP的时候才能够被信任。它们可以是IPv4地址,IPv4 CIDR,IPv6地址或IPv6 CIDR。
Note
默认情况下,不使用上面的函数设置信任的代理,那么默认信任所有的代理,但是这是不安全的。同时,如果您不使用任何代理,则可以使用
Engine.settrustedproxies(NIL)禁用此功能,然后Contect.ClientIP()将直接返回远程地址以避免进行一些不必要的计算。
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.SetTrustedProxies([]string{"192.168.1.2"})
router.GET("/", func(c *gin.Context) {
// 来源于信任的客户ip,会从X-Forwarded-For头中来推断出原始的客户端IP
// 否则简单返回直接交互的ip
fmt.Printf("ClientIP: %s\n", c.ClientIP())
})
router.Run()
}也就是说,如果客户端的IP是可信任的代理中的IP,那么可以通过其获取到最原始的客户端IP。否则,就直接将与其通信的IP当作客户端IP。
如果使用的是CDN服务,则可以设置Engine.trustedplatform以跳过可信赖的检查,它的优先级高于TrustedProxies。查看下面的示例:
import (
"fmt"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
// 使用预定义的头 gin.PlatformXXX
router.TrustedPlatform = gin.PlatformGoogleAppEngine
// 为你信任的代理服务设置你自己的信任请求头
// 不要将其设置为任何怀疑请求头,是不安全的
router.TrustedPlatform = "X-CDN-IP"
router.GET("/", func(c *gin.Context) {
// 如果设置了TrustedPlatform,ClientIP会解析对应的头并直接返回IP。
fmt.Printf("ClientIP: %s\n", c.ClientIP())
})
router.Run()
}tags: gin