Gin + Ant Design Pro JWT认证
文章目录
- 一:介绍
- 二:Gin JWT 后台
- 1. `Claims `定义
- 2. 创建和解析Token
- 3. Gin中间件编写
- 4. 辅助函数
- 三:Ant Design Pro JWT认证
- 四:Gin中间件和使用示范
一:介绍
- JWT现在比较流行的认证方式,微服务中使用特别常见。
- JWT标准格式
在HTTP请求添加名为Authorization的header,形式如下: (token前面
Bearer是标准前缀字符串)
Authorization: Bearer
- Go JWT 结构体
Claims,可以理解为需要保存的信息,加密后会存储在token中,解密后会从token自动解析出来
配合
ant design pro前端实现需要解决以下问题:
JWT TOKEN需要存储哪些字段以及定义,如何创建和解析- 前端发送请求时如何自动添加
JWT认证信息 JWT TOKEN过期后,前后端如何配合自动刷新
二:Gin JWT 后台
使用库
github.com/golang-jwt/jwt/v5
1. Claims 定义
jwt.RegisteredClaims是github.com/golang-jwt/jwt/v5预设的标准claims,后面用到其ExpiresAt过期时间字段,UserClaims为自定义存储的字段,最终加密到token中的是jwtClaims结构
type UserClaims struct {
// 可以添加字段存储其他信息UserID uint `json:"userId"`RoleID uint `json:"roleId"`UserName string `json:"username"`
}type jwtClaims struct {UserClaimsjwt.RegisteredClaims
}
2. 创建和解析Token
expireHours和refreshHours分别是设置过期时间,以及距离过期时间多久返回新token,后续在gin中间件中判断,方式是在Header中返回x-refresh-token:newToken
type JWT struct {secret []byteexpireHours time.TimerefreshHours time.Duration
}// j := NewJWT("密钥", 2, 1)
// token过期时间是2小时, 距离过期时间还有1小时时在`Header`中返回`x-refresh-token`:`newToken`
func NewJWT(secret string, expireHours int, refreshHours int) *JWT {return &JWT{secret: []byte(secret),expireHours: time.Now().Add(time.Duration(expireHours) * time.Hour),refreshHours: time.Hour * time.Duration(refreshHours),}
}func (j *JWT) CreateToken(u UserClaims) (string, error) {token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims{UserClaims: u,RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(j.expireHours),IssuedAt: jwt.NewNumericDate(time.Now()),},})return token.SignedString(j.secret)
}func (j *JWT) ParseToken(tokenString string) (*jwtClaims, error) {token, err := jwt.ParseWithClaims(tokenString, &jwtClaims{}, func(token *jwt.Token) (interface{}, error) {return j.secret, nil})if err != nil {return nil, err}if claims, ok := token.Claims.(*jwtClaims); ok && token.Valid {return claims, nil} else {return nil, errors.New("Token无效")}
}
3. Gin中间件编写
type BaseResponse struct {Success bool `json:"success"`Data any `json:"data"`Message string `json:"message"`ErrorMessage string `json:"errorMessage"`
}func OkWithData(c *gin.Context, data any) {c.JSON(200, BaseResponse{Success: true, Data: data})
}func OkWithMsg(c *gin.Context, msg string) {c.JSON(200, BaseResponse{Success: true, Message: msg})
}func Fail(c *gin.Context, errMsg string) {c.JSON(200, BaseResponse{Success: false, ErrorMessage: errMsg})
}
// 使用如下:
// // token过期时间是2小时, 距离过期时间还有1小时时在`Header`中返回`x-refresh-token`:`newToken`
// j := NewJWT("密钥", 2, 1)
// r.USE(JWTAuth(j))
func JWTAuth(j *JWT) gin.HandlerFunc {return func(c *gin.Context) {token := c.Request.Header.Get("Authorization")token = strings.TrimPrefix(token, "Bearer ")claims, err := j.ParseToken(token)if err != nil {response.Fail(c, "Token错误: "+err.Error())c.Abort()return}if time.Since(claims.ExpiresAt.Local()) < j.refreshHours {newToken, err := j.CreateToken(claims.UserClaims)if err != nil {response.Fail(c, "Token刷新错误: "+err.Error())c.Abort()return}c.Header("x-refresh-token", newToken)}c.Set("claims", claims)c.Next()}}
4. 辅助函数
gin中直接调用该函数可以方便的获取到存储的机构体信息
func GetUserToken(c *gin.Context) *UserClaims {claims, _ := c.Get("claims")if claims == nil {return &UserClaims{}}return &claims.(*jwtClaims).UserClaims
}
三:Ant Design Pro JWT认证
处理登录请求后返回
jwt token使用localStorage.setItem('jwt', token)存储起来
app.tsx的文件request定义中添加拦截器,实现方法:
- 请求前,在
header中添加头·Authorization·: 'Bearer ’ + localStorage.getItem(‘jwt’) || ‘’- 请求后,检测
header中是否存在x-refresh-token,存在的话更新token,目的是防止token过期自动刷新
实现如下:
function setToken(token: string) {localStorage.setItem('jwt', token);
}function getToken(): string {return localStorage.getItem('jwt') || '';
}export const request = {...errorConfig,// 请求前拦截器requestInterceptors: [(url: string, options: RequestConfig) => {const authHeader = { Authorization: 'Bearer ' + getToken() };return {url: `${url}`,options: { ...options, interceptors: true, headers: authHeader },};},],// 请求后拦截器responseInterceptors: [(response: Response, options: RequestConfig) => {if (response.headers.has('x-refresh-token')) {setToken(response.headers.get('x-refresh-token') || '');}return response;},],
};
四:Gin中间件和使用示范
jwt_middleware.go
package middlewareimport ("errors""strings""time""github.com/gin-gonic/gin""github.com/golang-jwt/jwt/v5"
)// 可以添加字段存储其他信息
type UserClaims struct {UserID uint `json:"userId"`RoleID uint `json:"roleId"`UserName string `json:"username"`
}type jwtClaims struct {UserClaimsjwt.RegisteredClaims
}type JWT struct {secret []byteexpireHours time.TimerefreshHours time.Duration
}// j := NewJWT("密钥", 2, 1)
// token过期时间是2小时, 距离过期时间还有1小时时在`Header`中返回`x-refresh-token`:`newToken`
func NewJWT(secret string, expireHours int, refreshHours int) *JWT {return &JWT{secret: []byte(secret),expireHours: time.Now().Add(time.Duration(expireHours) * time.Hour),refreshHours: time.Hour * time.Duration(refreshHours),}
}func (j *JWT) CreateToken(u UserClaims) (string, error) {token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims{UserClaims: u,RegisteredClaims: jwt.RegisteredClaims{ExpiresAt: jwt.NewNumericDate(j.expireHours),IssuedAt: jwt.NewNumericDate(time.Now()),},})return token.SignedString(j.secret)
}func (j *JWT) ParseToken(tokenString string) (*jwtClaims, error) {token, err := jwt.ParseWithClaims(tokenString, &jwtClaims{}, func(token *jwt.Token) (interface{}, error) {return j.secret, nil})if err != nil {return nil, err}if claims, ok := token.Claims.(*jwtClaims); ok && token.Valid {return claims, nil} else {return nil, errors.New("Token无效")}
}// 使用如下:
// // token过期时间是2小时, 距离过期时间还有1小时时在`Header`中返回`x-refresh-token`:`newToken`
// j := NewJWT("密钥", 2, 1)
// r.USE(JWTAuth(j))
func JWTAuth(j *JWT) gin.HandlerFunc {return func(c *gin.Context) {token := c.Request.Header.Get("Authorization")token = strings.TrimPrefix(token, "Bearer ")claims, err := j.ParseToken(token)if err != nil {response.Fail(c, "Token错误: "+err.Error())c.Abort()return}if time.Since(claims.ExpiresAt.Local()) < j.refreshHours {newToken, err := j.CreateToken(claims.UserClaims)if err != nil {response.Fail(c, "Token刷新错误: "+err.Error())c.Abort()return}c.Header("x-refresh-token", newToken)}c.Set("claims", claims)c.Next()}}func GetUserToken(c *gin.Context) *UserClaims {claims, _ := c.Get("claims")if claims == nil {return &UserClaims{}}return &claims.(*jwtClaims).UserClaims
}type BaseResponse struct {Success bool `json:"success"`Data any `json:"data"`Message string `json:"message"`ErrorMessage string `json:"errorMessage"`
}func OkWithData(c *gin.Context, data any) {c.JSON(200, BaseResponse{Success: true, Data: data})
}func OkWithMsg(c *gin.Context, msg string) {c.JSON(200, BaseResponse{Success: true, Message: msg})
}func Fail(c *gin.Context, errMsg string) {c.JSON(200, BaseResponse{Success: false, ErrorMessage: errMsg})
}
main.go
package middlewareimport ("fmt""github.com/gin-gonic/gin"
)func main() {j := NewJWT("密钥", 2, 1)r := gin.Default()r.POST("/login", func(ctx *gin.Context) {// 处理登录逻辑返回token, 前端需讲token存储到localstoragetoken, err := j.CreateToken(UserClaims{UserID: 1, RoleID: 1, UserName: "Leo"})if err != nil {response.Fail(ctx, err.Error())return}response.OkWithData(ctx, gin.H{"token": token})})auth := r.Group("/api")auth.Use(JWTAuth(j))auth.GET("/test", func(ctx *gin.Context) {u := GetUserToken(ctx)response.OkWithMsg(ctx, fmt.Sprintf("用户ID:%d角色ID:%d用户名:%s", u.UserID, u.RoleID, u.UserName))})
}相关文章:
Gin + Ant Design Pro JWT认证
文章目录 一:介绍二:Gin JWT 后台1. Claims 定义2. 创建和解析Token3. Gin中间件编写4. 辅助函数 三:Ant Design Pro JWT认证四:Gin中间件和使用示范 一:介绍 JWT现在比较流行的认证方式,微服务中使用特别…...
canvas实现图片标注,绘制区域
使用canvas绘制通过多边形标注区域 AI视频项目中需要分析图片,需要前台绘制区域,后端获取坐标然后识别图像,通过canvas 获取点然后连线绘图 HEML代码段 <div class"areaDrawing"><img src"/assets/images/snapPhotos…...
SELECT COUNT(*) 会造成全表扫描吗?
前言 SELECT COUNT(*)会不会导致全表扫描引起慢查询呢? SELECT COUNT(*) FROM SomeTable 网上有一种说法,针对无 where_clause 的 COUNT(*),MySQL 是有优化的,优化器会选择成本最小的辅助索引查询计数,其实反而性能…...
python考前复习(90题)
文章目录 1.Python特性的是( )。 A. 面向对象 B. 高可移植性 C. 开源、免费 2.临时改变Python语言安装源应当使用的选项是 –index-url 3.Python脚本文件的扩展名为( ) .py 4.安装Python语言的软件包使用的命令是( ) pip install 5 . (单选题)以下哪项是…...
根据SpringBoot Guides完成进行示例学习(详细步骤)
目录 1.打开Spring | Guides官网,或者直接搜索springboot都可 2.选择要学习的内容 3.根据提示的网址,Git到本地 4.将文件用IDEA打开,根据教程完成示例,这里不做细致讲解 5.运行项目 6.在终端查看运行结果 以Scheduling Task…...
waf、yakit和ssh免密登录
WAF安全狗 脏数据适用于所有漏洞绕过waf,但是前提条件垃圾信息必须放在危险信息前,是不能打断原有数据包的结构,不能影响后端对数据包的解析。 以DVWA靶场文件上传为例 新建php文件 上传文件被安全狗拦截 使用bp抓包查看 在数据包Content-…...
【AIGC核心技术剖析】大型语言和视觉助手——LLaVA(论文+源码)
🔥 [新!LLaVA-1.5 在 11 个基准测试上实现了 SoTA,只需对原始 LLaVA 进行简单的修改,利用所有公共数据,在单个 1-A8 节点上在 ~100 天内完成训练,并超越使用数十亿级数据的方法。 LLaVA代表了一种新颖的端到端训练大型多模态模型,结合了视觉编码器和骆马 对于通用的视…...
IBM的WAS简介与基本使用手册
IBM的WAS简介与基本使用手册 1. 基本介绍 WebSphereApplication Server(简称WAS)是IBM的应用服务器 基本结构:单元(cell) ——> 多个节点(node) ——> 多个服务(server) ——> 多个应用(app) 单元是整个分布式网络中一个或多个节点的逻辑分组单元是一个配置概念, 是…...
Deno 快速入门
目录 1、简介 2、安装Deno MacOS下安装 Windows下安装 Linux 下安装 3、创建并运行TypeScript程序 4、内置Web API和Deno命名空间 5、运行时安全 6、导入JavaScript模块 7、远程模块和Deno标准库 8、使用deno.json配置您的项目 9、Node.js API和npm包 10、配置IDE…...
【计算机网络笔记】OSI参考模型基本概念
系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)…...
ConnectTimeout和ReadTimeout所代表的意义
ConnectTimeout和ReadTimeout所代表的意义 ConnectTimeout 指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间。在java中,网络状况正常的情况下,例如使用HttpClient或者HttpURLConnetion连接时设置参数c…...
使用Python计算平面多边形间最短距离,数据需要从excel表格中导入
使用Python计算平面多边形间最短距离,数据需要从excel表格中导入, * 多边形种类包括(圆形、矩形、六边形、五边形、跑道形/胶囊形), * Python代码需要使用gjk算法进行判断两个多边形间是否重叠, * 如果未重…...
华为数通方向HCIP-DataCom H12-831题库(多选题:1-20)
第01题 如图所示,路由器所有的接口开启OSPF,图中标识的ip地址为设备的Loopback0接口的IP地址,R1、R2,R3的Loopback0通告在区域1,R4的Loopback0通告在区域0、R5的Lopback0通告在区域2,下列哪些IP地址之间可以相互Ping通? A、10.0.3.3和10.0.5.5 B、10.0.4.4和10.0.2.2 …...
CCC数字钥匙设计【NFC】--通过NFC进行车主配对Phase3
1、车主配对流程介绍 车主配对可以通过车内NFC进行,若支持UWB测距,也可以通过蓝牙/UWB进行。通过NFC进行车主配对总共有5个Phase。本文档主要对Phase3进行介绍。 1) Phase0:准备阶段; 2) Phase1:启动流程࿱…...
开源OA协同办公系统,集成Flowable流程引擎 可拖拽创建个性表单
源码下载:https://download.csdn.net/download/m0_66047725/88403340 源码下载2: 关注我留言 开源OA协同办公系统,集成Flowable流程引擎 可拖拽创建个性表单。基于RuoYi-VUE版本开发。 1、使用RuoYi-Vue的基础上开发。 2、集成flowable&a…...
为什么嵌入通常优于TF-IDF:探索NLP的力量
塔曼纳 一、说明 自然语言处理(NLP)是计算机科学的一个领域,涉及人类语言的处理和分析。它用于各种应用程序,例如聊天机器人、情绪分析、语音识别等。NLP 中的重要任务之一是文本分类,我们根据文本的内容将文本分类为不…...
oracle-AWR报告生成方法
AWR报告生成方法 1. 以oracle用户登陆服务器 2. 进入到要保存awr报告的目录 3. 以sysdba身份连接数据库 sqlplus / as sysdba4. 执行生成AWR报告命令 ?/rdbms/admin/awrrpt.sql5. 选择AWR报告的文件格式 6. 选择生成多少天的AWR报告 7. 选择报告的快照起始和结束ID 8. 输入生…...
笙默考试管理系统-MyExamTest----codemirror(37)
笙默考试管理系统-MyExamTest----codemirror(36) 目录 一、 笙默考试管理系统-MyExamTest 二、 笙默考试管理系统-MyExamTest 三、 笙默考试管理系统-MyExamTest 四、 笙默考试管理系统-MyExamTest 五、 笙默考试管理系统-MyExamTest 笙默考试…...
【Unity3D编辑器拓展】Unity3D的IMGUI、GUI、GUILayout、EditorGUI、EditorGUILayout、OnGUI【全面总结】
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 在开发中,常常会遇到要使用OnGUI的地方。 也会遇到…...
11. 机器学习 - 评价指标2
文章目录 混淆矩阵F-scoreAUC-ROC 更多内容: 茶桁的AI秘籍 Hi, 你好。我是茶桁。 上一节课,咱们讲到了评测指标,并且在文章的最后提到了一个矩阵,我们就从这里开始。 混淆矩阵 在我们实际的工作中,会有一个矩阵&am…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
