auth.go
/**
* @Description: ip拦截器
* @Author: Walker
* @Date: 2021/4/16
*/
package auth
import (
"github.com/gin-gonic/gin"
"net/http"
ip2 "wxtokenmicroservice/service/ip"
service "wxtokenmicroservice/utils/ip"
)
//返回类型:HandlerFunc
func IpAuthorize() gin.HandlerFunc {
return func(c *gin.Context) {
//获取ip
ip := service.GetRealIp(c.Request)
//查询数据库是否存在该ip
res := ip2.IfExistsIp(ip)
if res == 1 {
// 验证通过,会继续访问下一个中间件
c.Next()
} else {
// 验证不通过,不再调用后续的函数处理
c.Abort()
c.JSON(http.StatusUnauthorized, gin.H{
"code": 401,
"message": "访问未授权",
"data": res,
})
// return可省略, 只要前面执行Abort()就可以让后面的handler函数不再执行
return
}
}
}
获取ip
package service
import (
"net"
"net/http"
"strconv"
"strings"
)
// ClientIP 尽最大努力实现获取客户端 IP 的算法。
// 解析 X-Real-IP 和 X-Forwarded-For 以便于反向代理(nginx 或 haproxy)可以正常工作。
func ClientIp(r *http.Request) string {
xForwardedFor := r.Header.Get("X-Forwarded-For")
ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
if ip != "" {
return ip
}
ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
if ip != "" {
return ip
}
ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr))
if err == nil {
return ip
}
return ""
}
// ClientPublicIP 尽最大努力实现获取客户端公网 IP 的算法。
// 解析 X-Real-IP 和 X-Forwarded-For 以便于反向代理(nginx 或 haproxy)可以正常工作。
func ClientPublicIP(r *http.Request) string {
var ip string
for _, ip = range strings.Split(r.Header.Get("X-Forwarded-For"), ",") {
ip = strings.TrimSpace(ip)
if ip != "" && !IsLocalIp(ip) {
return ip
}
}
ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
if ip != "" && !IsLocalIp(ip) {
return ip
}
if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
if !IsLocalIp(ip) {
return ip
}
}
return ""
}
func IsLocalIp(ip string) bool {
/*
局域网(intranet)的IP地址范围包括:
10.0.0.0/8--10.0.0.0~10.255.255.255(A类)
172.16.0.0/12-172.16.0.0-172.31.255.255(B类)
192.168.0.0/16--192.168.0.0~192.168.255.255(C类)
*/
ipAddr := strings.Split(ip, ".")
if strings.EqualFold(ipAddr[0], "10") {
return true
} else if strings.EqualFold(ipAddr[0], "172") {
addr, _ := strconv.Atoi(ipAddr[1])
if addr >= 16 && addr < 31 {
return true
}
} else if strings.EqualFold(ipAddr[0], "192") && strings.EqualFold(ipAddr[1], "168") {
return true
}
return false
}
func GetRealIp(r *http.Request) string {
ip := ClientPublicIP(r)
if ip == "" {
ip = ClientIp(r)
}
return ip
}
router.go
func InitRouter() *gin.Engine {
router := gin.Default()
v1 := router.Group("/v1")
{
/*不需要进行ip拦截的api*/
//这个api不会被拦截
router.POST("/v1/corp/add", corp.AddCorpCode)
}
router.Use(auth.IpAuthorize()) //分界线,开启认证
/*需要进行ip拦截的api*/
{
//这个api就会被拦截
v1.POST("/corp/delete", corp.DelCorpCode)
}
return router
}