gin中间件

gin中间件的作用

  • 请求到达http请求处理方法之前,拦截请求:
    • 认证
    • 权限校验
    • 限流
    • 数据过滤
    • ip白名单
  • 处理完请求后,拦截响应,并进行相应的处理
    • 统一添加响应头
    • 数据过滤

gin中间件的定义

中间件就是一个以gin.Context为形参的函数:

type HandlerFunc func(*Context)

gin内置中间件

func BasicAuth(accounts Accounts) HandlerFunc
func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc
func Bind(val interface{}) HandlerFunc //拦截请求参数并进行绑定
func ErrorLogger() HandlerFunc       //错误日志处理
func ErrorLoggerT(typ ErrorType) HandlerFunc //自定义类型的错误日志处理
func Logger() HandlerFunc //日志记录
func LoggerWithConfig(conf LoggerConfig) HandlerFunc
func LoggerWithFormatter(f LogFormatter) HandlerFunc
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc
func Recovery() HandlerFunc
func RecoveryWithWriter(out io.Writer) HandlerFunc
func WrapF(f http.HandlerFunc) HandlerFunc //将http.HandlerFunc包装成中间件
func WrapH(h http.Handler) HandlerFunc //将http.Handler包装成中间件

gin中间件的位置

  • 全局
  • 路由组
  • 路由明细

gin中间件的使用

gin默认使用中间件

func Default() *Engine {
    debugPrintWARNINGDefault()
    engine := New()
    engine.Use(Logger(), Recovery())//使用Recovery和Logger中间
    return engine
}

从上面源码中可以看到,gin.Default()返回的gin.Engine已经默认使用了Recovery和Logger中间件。
当不想使用这两个中间件时,可以使用gin.New()返回一个不带中间件的gin.Engine对象:router:=gin.New()

单个路由使用中间件

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	router := gin.Default()
	router.GET("/", gin.Recovery(), gin.Logger(), func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"msg": "single route"})
	})

	router.Run(":8080")
}


路由分组使用中间件

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	router := gin.Default()
	v1 := router.Group("/v1", gin.Logger(), gin.Recovery())
	{
		v1.GET("/test1", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"res": "test1"})
		})
		v1.GET("/test2", func(c *gin.Context) {
			c.JSON(http.StatusOK, gin.H{"res": "test2"})
		})
	}

	router.Run(":8080")
}


全局中间件

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	router := gin.Default()
	router.Use(func(c *gin.Context) {
		fmt.Println("hello middleware")
	})

	router.GET("/", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"status": "OK"})
	})

	router.Run(":8080")
}

传参

//gin set get取参数
func (c *Context) Set(key string, value interface{})
func (c *Context) Get(key string) (value interface{}, exists bool) //判断key是否存在 c.Get

func (c *Context) GetBool(key string) (b bool)
func (c *Context) GetDuration(key string) (d time.Duration)
func (c *Context) GetFloat64(key string) (f64 float64)
func (c *Context) GetInt(key string) (i int)
func (c *Context) GetInt64(key string) (i64 int64)
func (c *Context) GetString(key string) (s string)
func (c *Context) GetStringMap(key string) (sm map[string]interface{})
func (c *Context) GetStringMapString(key string) (sms map[string]string)
func (c *Context) GetStringMapStringSlice(key string) (smss map[string][]string)
func (c *Context) GetStringSlice(key string) (ss []string)
func (c *Context) GetTime(key string) (t time.Time)

func (c *Context) MustGet(key string) interface{} //必须有, 否则panic
package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

func Middleware1(c *gin.Context) {
	c.Set("key1", 123)
	c.Set("key2", "renwoxing")

}
func main() {
	router := gin.New()
	router.GET("/", Middleware1, func(c *gin.Context) {
		key1 := c.GetInt("key1")
		key2 := c.GetString("key2")
		c.JSON(http.StatusOK, gin.H{
			"key1": key1,
			"key2": key2,
		})
	})
	router.Run(":8080")
}

自定义中间件

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

func main() {
	router := gin.Default()
	router.Use(MyMiddleware())
	router.GET("/", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"res": "user define middleware"})
	})

	router.Run(":8080")
}

func MyMiddleware() gin.HandlerFunc {
	//中间件逻辑处理
	fmt.Println("todo....")

	return func(c *gin.Context) {
		fmt.Println("return middleware")
	}
}

使用gin.BasicAutn

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
)

// 模拟数据
var secrets = gin.H{
	"zhangsan": gin.H{"email": "zhangsan@example.com", "phone": "123456"},
	"lisi":     gin.H{"email": "lisi@example.com", "phone": "123456"},
	"wangwu":   gin.H{"email": "wangwu@example.com", "phone": "123456"},
}

func main() {
	router := gin.Default()
	router.GET("/", func(c *gin.Context) {
		c.JSON(http.StatusOK, secrets)
	})
	// 为/admin路由组设置auth, 路由组使用 gin.BasicAuth() 中间件
	auth := router.Group("/admin", gin.BasicAuth(gin.Accounts{
		"zhangsan": "zhangsan",
		"lisi":     "lisi",
		"wangwu":   "wangwu",
	}))

	// /admin/secrets 端点
	auth.GET("/secrets", func(c *gin.Context) {
		//获取用户名
		user := c.MustGet(gin.AuthUserKey).(string)
		if secret, ok := secrets[user]; ok {
			c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
		} else {
			c.JSON(http.StatusOK, gin.H{"user": user, "secret": "No secret"})
		}

	})
	router.Run(":8080")
}

计算响应时间

package main

import (
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"time"
)

func statCost() gin.HandlerFunc {
	return func(c *gin.Context) {
		t := time.Now()
		c.Set("test", "123456")
		// 请求前逻辑
		c.Next()
		//请求后逻辑
		latency := time.Since(t)
		log.Printf("total spend time: %d us", latency/1000)

	}

}

func main() {
	router := gin.Default()
	router.Use(statCost())
	router.GET("/", func(c *gin.Context) {
		test := c.MustGet("test").(string)
		log.Println(test)
		c.JSON(http.StatusOK, gin.H{"msh": "success"})
	})
	router.Run(":8080")
}

Gin框架中,JWT(JSON Web Token)是一种常用的身份验证和授权机制。JWT是一种基于JSON的开放标准(RFC 7519),用于在网络应用间传递信息。它由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。 在Gin中使用JWT中间件可以实现对请求进行身份验证和授权。下面是使用Gin中间件JWT的步骤: 1. 导入相关的包: ```go import ( "github.com/gin-gonic/gin" "github.com/dgrijalva/jwt-go" ) ``` 2. 定义JWT中间件: ```go func AuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { tokenString := c.GetHeader("Authorization") if tokenString == "" { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) c.Abort() return } token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { // 验证签名的密钥 return []byte("secret"), nil }) if err != nil || !token.Valid { c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) c.Abort() return } // 将解析后的token存储到上下文中,方便后续处理 c.Set("token", token) c.Next() } } ``` 3. 在需要进行身份验证和授权的路由上使用中间件: ```go router := gin.Default() router.GET("/protected", AuthMiddleware(), func(c *gin.Context) { // 从上下文中获取解析后的token token := c.MustGet("token").(*jwt.Token) // 在这里可以进行进一步的处理,如获取用户信息等 // ... c.JSON(http.StatusOK, gin.H{"message": "Authorized"}) }) router.Run(":8080") ``` 这样,当访问`/protected`路由时,会先经过JWT中间件进行身份验证和授权,只有在验证通过的情况下才会执行后续的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值