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. Pytorch 看起来好像没占gpu的样子的原因

    今天好哥们儿赞助的3080到手了,欣喜若狂的装上 然后跑了跑MNIST,看着任务管理器CPU跑100%,GPU跑3%,查了半天解决不了,郁闷了好一会儿.. 后来在https://www.bilibil ...

  2. 推荐一个Elasticsearch ES可视化客户端工具:ES-King

    ES-King:开源免费,一个现代.实用的ES GUI客户端,支持多平台. 下载地址:https://github.com/Bronya0/ES-King 功能清单 详尽的集群信息:节点信息.堆内存占 ...

  3. 五分钟扫盲:25个工作中常用的Linux命令

    目录 §基础篇 cd 命令 ls / ll 和 clear 命令 grep 命令 : 查找关键字 find命令 kill tail cp命令 mv命令 rm命令 mkdir命令 rmdir 命令 ca ...

  4. 做Data+AI的长期主义者 | 倒计时2天...

    <数据资产管理白皮书>下载地址: https://www.dtstack.com/resources/1073/?src=bbs <行业指标体系白皮书>下载地址: https: ...

  5. 开源技术交流丨ChengYing部署Hadoop集群实战

    一.直播介绍 上期雅泽同学对ChengYing是什么.有什么样的功能特性,如何快速入门做了介绍,本期海洋同学将会为大家分享ChengYing部署Hadoop集群实战的相关内容,欢迎大家积极参与. 二. ...

  6. 未能加载文件或程序集“System.Runtime.WindowsRuntime, Version=4.0.14.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”或它的某一个依赖项。不应出于执行的目的加载引用程序集。只能在仅限反射的加载程序上下文中加载引用程序集。 (异常来自 HRESULT:0x80131058)

    VS项目编译时报错: 未能加载文件或程序集"System.Runtime.WindowsRuntime, Version=4.0.14.0, Culture=neutral, PublicK ...

  7. Java学习篇(二)—— C++和Java的区别之程序内存分布

    上一篇介绍了C++和Java编译的区别和Java独有的网络编程,线程管理.这一篇主要介绍一下两者在程序运行时的内存空间. 内存分布 项目 C++ 程序 Java 程序(使用 JVM) 编译结果 直接生 ...

  8. HDFS目录配额(quota)不足导致写文件失败

    本文分享自天翼云开发者社区<HDFS目录配额(quota)不足导致写文件失败>,作者:5****m 问题背景与现象 给某目录设置quota后,往目录中写文件失败,出现如下问题"T ...

  9. 深入掌握iostat:运维必备的I/O性能分析利器

    在Linux系统运维中,磁盘I/O性能往往是系统瓶颈的关键来源.iostat作为sysstat工具包中的核心命令,能够实时监控CPU使用率和磁盘I/O统计,是性能诊断不可或缺的工具.本文将全面解析io ...

  10. java基础——数据类型转换

    数据类型转换: 小数据类型-------->大数据类型 自动类型转换 大数据类型--------->小数据类型 强制类型转换 强制类型转换的格式 小数据类型 变量名 = (小数据类型)大数 ...