Gin中间件开发与鉴权实践

1. 中间件执行流程

[客户端请求]

[Logger中间件] → 记录请求开始时间

[CORS中间件] → 处理跨域请求

[JWT鉴权] → 验证访问令牌

[RBAC鉴权] → 校验用户权限

[业务处理] → 核心业务逻辑

[Logger中间件] ← 记录响应耗时

2. JWT鉴权完整实现

2.1 生成JWT令牌

func GenerateToken(userID string, roles []string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"userID": userID,
"roles": roles,
"exp": time.Now().Add(8 * time.Hour).Unix(),
})
return token.SignedString([]byte(os.Getenv("JWT_SECRET")))
}

2.2 鉴权中间件

func JWTAuth() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := strings.TrimPrefix(c.GetHeader("Authorization"), "Bearer ") token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte(os.Getenv("JWT_SECRET")), nil
}) if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
c.Set("userID", claims["userID"])
c.Set("roles", claims["roles"])
c.Next()
} else {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
}
}
}

3. RBAC权限中间件

func RequireRole(role string) gin.HandlerFunc {
return func(c *gin.Context) {
roles, exists := c.Get("roles")
if !exists {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "access denied"})
return
} for _, r := range roles.([]string) {
if r == role {
c.Next()
return
}
}
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "insufficient permissions"})
}
}

4. 跨域中间件配置

func CORSMiddleware() gin.HandlerFunc {
return cors.New(cors.Config{
AllowOrigins: []string{"https://prod.com", "http://localhost:3000"},
AllowMethods: []string{"GET", "POST", "PUT", "PATCH"},
AllowHeaders: []string{"Origin", "Content-Type", "Authorization"},
ExposeHeaders: []string{"Content-Length"},
AllowCredentials: true,
MaxAge: 12 * time.Hour,
})
}

5. 中间件调试技巧

  1. 上下文数据追踪
// 在中间件中添加调试信息
c.Set("requestID", uuid.NewString())
log.Printf("[%s] %s %s", c.GetString("requestID"), c.Request.Method, c.Request.URL)
  1. 中间件执行顺序验证
router.Use(
middleware.LatencyLogger(),
middleware.CORSMiddleware(),
middleware.JWTAuth(),
)

6. 单元测试方案

6.1 中间件测试示例

func TestJWTMiddleware(t *testing.T) {
router := gin.New()
router.Use(JWTAuth())
router.GET("/test", func(c *gin.Context) {
c.Status(http.StatusOK)
}) // 有效令牌测试
t.Run("valid token", func(t *testing.T) {
token, _ := GenerateToken("user123", []string{"admin"})
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/test", nil)
req.Header.Set("Authorization", "Bearer "+token)
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
})
}

6.2 测试覆盖率统计

# 生成测试覆盖率报告
go test -coverprofile=coverage.out
go tool cover -html=coverage.out

最佳实践

  1. 中间件链式调用示例:
router.Use(
middleware.Recovery(),
middleware.CORSMiddleware(),
middleware.JWTAuth(),
middleware.RequireRole("admin"),
middleware.RequestLogger(),
)
  1. 敏感信息过滤:
// 在日志中间件中过滤敏感字段
if strings.Contains(c.Request.URL.Path, "/auth") {
c.Writer = &responseWrapper{c.Writer, c}
}

03Gin中间件开发与鉴权实践的更多相关文章

  1. SpringCloud 2020.0.4 系列之 JWT用户鉴权

    1. 概述 老话说的好:善待他人就是善待自己,虽然可能有所付出,但也能得到应有的收获. 言归正传,之前我们聊了 Gateway 组件,今天来聊一下如何使用 JWT 技术给用户授权,以及如果在 Gate ...

  2. 测试开发【Mock平台】04实战:前后端项目初始化与登录鉴权实现

    [Mock平台]为系列测试开发教程,从0到1编码带你一步步使用Spring Boot 和 Antd React 框架完成搭建一个测试工具平台,希望作为一个实战项目能为你的测试开发学习有帮助. 一.后端 ...

  3. Onvif开发之客户端鉴权获取参数篇

    前面一篇已经介绍了客户端如何发些设备,下面这篇简单介绍下在发现设备后,如何通过ONVIF协议来获取设备的相关参数 ONVIF中不管是客户端还是设备端,最先实现的接口都是关于能力的那个接口,在客户端实现 ...

  4. EasyNVR摄像机网页H5全平台无插件直播流媒体播放服务二次开发之接口鉴权示例讲解

    背景需求 EasyNVR的使用者应该都清楚的了解到,EasyNVR一个强大的功能就是可以进行全平台的无插件直播.主要原因在于rtsp协议的视频流(默认是需要插件才可以播放的)经由EasyNVR处理可以 ...

  5. web开发常见的鉴权方式

    结合网上找的资料整理了一下,以下是web开发中常见的鉴权方法: 预备:一些基本的知识 RBAC(Role-Based Access Control)基于角色的权限访问控制(参考下面①的连接) l    ...

  6. 【Gin-API系列】Gin中间件之鉴权访问(五)

    在完成中间件的介绍和日志中间件的代码后,我们的程序已经基本能正常跑通了,但如果要上生产,还少了一些必要的功能,例如鉴权.异常捕捉等.本章我们介绍如何编写鉴权中间件. 鉴权访问,说白了就是给用户的请求增 ...

  7. Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第一篇(内附开发 demo)

    简介 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系. 系列 云原生 API 网关,gRPC-Gateway V2 初探 业务流程 官方开发接入文档 ...

  8. Spring Security 接口认证鉴权入门实践指南

    目录 前言 SpringBoot 示例 SpringBoot pom.xml SpringBoot application.yml SpringBoot IndexController SpringB ...

  9. 【十次方微服务后台开发】Day02:加密与JWT鉴权、微服务注册中心、配置中心、熔断器、网关、消息总线、部署与持续集成、容器管理与监控Rancher、influxDB、grafana

    一.密码加密与微服务鉴权JWT 1.BCrypt密码加密 Spring Security 提供了BCryptPasswordEncoder类,实现Spring的PasswordEncoder接口使用B ...

  10. SpringBoot 拦截器妙用,让你一个人开发整个系统的鉴权模块!

    我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. Han ...

随机推荐

  1. VitePress 集成 Twikoo 评论

    Twikoo 是一个简洁.安全.免费的静态网站评论系统. 主要特点:免费搭建,部署简单,功能很完善,隐私护安全,通知发邮件,管理有内嵌,总之免费又方便 关于后端部署,大家可以看官网,或者这篇 Vite ...

  2. C语言:高级语言怎样抽象执行逻辑

    平时我们做编程的时候,底层 CPU 如何执行指令已经被封装好了,因此你很少会想到把底层和语言编译联系在一起.但从我自己学习各种编程语言的经历看,从这样一个全新视角重新剖析 C 语言,有助于加深你对它的 ...

  3. 补充停牌的日K数据

    问题 从TuShare获取的数据,停牌日是没有数据的,这将会在回测时,不能直接参与账户的净值计算,导致账户的净值以及收益计算不准确. 停盘 股票由于某种消息或进行某种活动引起股价的连续上涨或下跌,由证 ...

  4. 单服务器高性能模式:PPC与TPC

    极客时间:<从 0 开始学架构>:单服务器高性能模式:PPC与TPC 1.引言 高性能是系统中最复杂的一环,其中磁盘.操作系统.CPU.内存.缓存.网络.编程语言.架构等,每个都有可能影响 ...

  5. INotifyCollectionChanged 用法简介

    INotifyCollectionChanged 接口是 System.Collections.Specialized 命名空间中的一个接口,用于在集合发生更改时通知订阅者.这个接口通常在实现了集合的 ...

  6. 轻松掌握Manim的.animate语法:让动画编程更简单

    在Manim中,.animate语法是一个非常实用的功能,它能让你的动画代码变得更加简洁和直观. 本文将详细介绍.animate语法,看看它是如何让动画制作变得更加简单又有趣,即使是编程新手也能轻松上 ...

  7. 揭秘C#异步编程核心机制:从状态机到线程池的全面拆解

    C#中的异步编程是一个强大且复杂的特性,它允许开发者编写非阻塞的代码,从而显著提升应用程序的响应性和吞吐量.本文将深入剖析异步编程的底层原理,从async和await关键字的工作机制,到状态机.任务调 ...

  8. Springboot笔记<3> 组件注入注解@Conditional与@import

    @Conditional @Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean. 创建ConfigConditional类和测试类Conf ...

  9. 改造jsp项目的alert框和confirm框

    背景 之前项目的模态框改造完成,业务也想把页面中的提示框和确认框也改造一下:这里记录一下改造中的细节. 之前项目中的提示框和确认框用的是浏览器自带的 alert 和 confirm.改造之前无法支持业 ...

  10. ORA-01555系列:一、ORA-01555错误的本质与原理

    我们的文章会在微信公众号IT民工的龙马人生和博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢! 由于博客中有大量代码,通过页面浏览效 ...