/**
* @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")//返回类型:HandlerFuncfuncIpAuthorize() gin.HandlerFunc {returnfunc(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)可以正常工作。funcClientIp(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)可以正常工作。funcClientPublicIP(r *http.Request)string{var ip stringfor_, 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""}funcIsLocalIp(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"){returntrue}elseif strings.EqualFold(ipAddr[0],"172"){
addr,_:= strconv.Atoi(ipAddr[1])if addr >=16&& addr <31{returntrue}}elseif strings.EqualFold(ipAddr[0],"192")&& strings.EqualFold(ipAddr[1],"168"){returntrue}returnfalse}funcGetRealIp(r *http.Request)string{
ip :=ClientPublicIP(r)if ip ==""{
ip =ClientIp(r)}return ip
}