admin_backend/middleware/GeoIp.go
2025-11-11 11:30:02 +08:00

51 lines
1.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package middleware
import (
"net"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/oschwald/geoip2-golang"
)
func GeoRedirect(mapping map[string]string, defaultHost string) gin.HandlerFunc {
db, err := geoip2.Open("./GeoLite2-Country/GeoLite2-Country.mmdb")
if err != nil {
// 如果打开失败,返回不执行重定向的中间件
return func(c *gin.Context) { c.Next() }
}
return func(c *gin.Context) {
defer c.Next()
// 获取真实客户端 IP考虑代理
ipStr := c.Request.Header.Get("X-Forwarded-For")
if ipStr == "" {
ipStr = c.ClientIP()
} else {
// X-Forwarded-For 可能是逗号分隔的列表,取第一个
ipStr = strings.TrimSpace(strings.Split(ipStr, ",")[0])
}
ip := net.ParseIP(ipStr)
if ip == nil {
return
}
record, err := db.Country(ip)
if err != nil {
return
}
iso := record.Country.IsoCode // 如 "US", "CN", "BR"
target, ok := mapping[iso]
if !ok {
target = defaultHost
}
// 如果目标域名与当前请求不同,重定向(保留路径/查询)
if target != "" && !strings.Contains(c.Request.Host, target) {
location := "https://" + target + c.Request.URL.RequestURI()
// 302 临时重定向;如需永久改用 http.StatusMovedPermanently
c.Redirect(http.StatusFound, location)
c.Abort()
return
}
}
}