使用gin实现ip拦截器

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
}

上一篇:leetcode 179. 最大数(排序)


下一篇:go学习笔记(一)