Gin实战5:实现JWT中间件


一 开篇

  • JWT核心优势:无状态设计、跨平台兼容性、自包含数据特性
  • 典型应用场景:前后端分离架构、微服务鉴权、移动端API安全

二 Gin框架中间件开发实战

  • 中间件架构设计
    func JwtMiddleware(secret string) gin.HandlerFunc {
        return func(c *gin.Context) {
            // 令牌提取与验证逻辑
        }
    }
    
  • 核心功能实现
    • 令牌提取策略:提取Header 中 Authorization 的值 Bearer+’ ‘+JWT
    • 令牌解析验证:使用jwt.ParseWithClaims方法解析
    • 上下文注入:将解析后的Claims存入context
  • 错误处理规范
    • 401响应标准化(JSON格式错误码)
    • 异常场景覆盖:过期/篡改/格式错误令牌

三 增加白名单

  • 实际开发中会有一部分API需要忽略JWT token验证,因此增加了白名单参数 最终代码如下:
func JwtMiddleware(writeList map[string]struct{}, secret string) gin.HandlerFunc {
	return func(c *gin.Context) {
		path := c.Request.URL.Path
		if _, ok := writeList[path]; ok {
			c.Next()
			return
		}
		tokenHeader := c.GetHeader("Authorization")
		if tokenHeader == "" || len(tokenHeader) < 7 || tokenHeader[:6] != "Bearer" {
			c.AbortWithStatusJSON(401, gin.H{
				"code":    401,
				"message": "token invalid",
			})
			return
		}
		tokenString := tokenHeader[len("Bearer "):]

		token, err := jwt.ParseWithClaims(tokenString, &biz.CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
			return []byte(secret), nil
		})
		if err != nil {
			c.AbortWithStatusJSON(401, gin.H{
				"code":    401,
				"message": "token invalid",
			})
			return
		}
		if claims, ok := token.Claims.(*biz.CustomClaims); ok && token.Valid {
			c.Set("user_id", claims.UserID)
			c.Set("username", claims.Username)
		} else {
			c.AbortWithStatusJSON(401, gin.H{
				"code":    401,
				"message": "token invalid",
			})
		}
		c.Next()
	}
}

四 使用JWT中间件

  • internal/routers/router.go 中使用中间件
mdls = append(mdls, middleware.JwtMiddleware(
		map[string]struct{}{
			"/v1/login": {},
		},
		conf.Jwt.Secret,
	))

五 验证中间件是否生效

1、增加API

r.GET("/v1/get", account.GetUser)

2、返回context中取得到的用户信息

func (a *AccountServer) GetUser(context *gin.Context) {
	userId, _ := context.Get("user_id")
	username, _ := context.Get("username")

	context.JSON(200, gin.H{
		"user_id":  userId,
		"username": username,
	})
}

3、使用 Apifox 请求时候增加Header 验证返回结果

六 总结

  • jwt中的信息不是加密存储的,base64解析后可以看到明文信息,因此在记录敏感信息时建议进行加密处理
  • 回复「Gin实战」获取代码
wx

关注公众号

©2017-2023 鲁ICP备17023316号-1 Powered by Hugo