JWT Token刷新实战:Go语言版
创作时间:
作者:
@小白创作中心
JWT Token刷新实战:Go语言版
引用
CSDN
等
6
来源
1.
https://blog.csdn.net/Gaorui678/article/details/139030661
2.
https://blog.csdn.net/weixin_44102152/article/details/138667173
3.
https://blog.csdn.net/hzb869168467/article/details/136310155
4.
https://www.cnblogs.com/XY-Heruo/p/18280787
5.
https://www.cnblogs.com/QiaoPengjun/p/18630890
6.
https://www.cnblogs.com/failymao/p/18059012
在现代Web应用开发中,JWT(JSON Web Tokens)已经成为主流的认证解决方案。然而,JWT Token的过期问题一直是开发者需要解决的重要课题。本文将通过Go语言及其流行的Gin框架,详细讲解如何高效可靠地实现JWT Token刷新功能。
JWT Token刷新原理
在JWT认证体系中,通常会使用两种Token:Access Token和Refresh Token。
- Access Token:用于访问受保护资源的凭据,有效期较短(如15分钟),以提高安全性。
- Refresh Token:用于在Access Token过期后获取新的Access Token,有效期较长,有时甚至是永久有效的。
刷新流程如下:
- 用户初次登录时,服务器返回Access Token和Refresh Token。
- 客户端在每次请求时携带Access Token。
- 当Access Token过期时,客户端使用Refresh Token请求新的Access Token。
- 服务器验证Refresh Token有效后,返回新的Access Token。
- 如果Refresh Token也过期或无效,用户需要重新登录。
Go语言实现JWT Token刷新
环境准备
首先,确保已经安装了必要的Go包:
go get -u github.com/gin-gonic/gin
go get -u github.com/golang-jwt/jwt/v5
代码实现
- 定义JWT相关结构体
package main
import (
"github.com/golang-jwt/jwt/v5"
"time"
)
// JWTClaims 包含用户ID和过期时间
type JWTClaims struct {
UserID uint `json:"user_id"`
jwt.RegisteredClaims
}
// JWTSecret 签名密钥
var JWTSecret = []byte("your-secret-key")
- 生成JWT Token
func GenerateToken(userID uint) (string, error) {
claims := JWTClaims{
UserID: userID,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * time.Minute)),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(JWTSecret)
}
- 刷新JWT Token
func RefreshToken(oldToken string) (string, error) {
token, err := jwt.ParseWithClaims(oldToken, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
return JWTSecret, nil
})
if err != nil {
return "", err
}
if claims, ok := token.Claims.(*JWTClaims); ok && token.Valid {
newClaims := JWTClaims{
UserID: claims.UserID,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * time.Minute)),
},
}
newToken := jwt.NewWithClaims(jwt.SigningMethodHS256, newClaims)
return newToken.SignedString(JWTSecret)
}
return "", errors.New("invalid token")
}
- Gin 路由配置
func main() {
r := gin.Default()
// 公开接口:登录
r.POST("/login", func(c *gin.Context) {
// 这里应该包含验证用户名和密码的逻辑
// 假设验证通过,生成Token
token, err := GenerateToken(1) // 假设用户ID为1
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"token": token})
})
// 受保护接口:需要JWT认证
protected := r.Group("/api")
protected.Use(AuthMiddleware())
{
protected.GET("/user", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "Welcome!"})
})
}
// Token刷新接口
r.POST("/refresh_token", func(c *gin.Context) {
var req struct {
Token string `json:"token" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
newToken, err := RefreshToken(req.Token)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid token"})
return
}
c.JSON(http.StatusOK, gin.H{"token": newToken})
})
r.Run(":8080")
}
- JWT认证中间件
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.GetHeader("Authorization")
if tokenString == "" {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
token, err := jwt.ParseWithClaims(tokenString, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
return JWTSecret, nil
})
if err != nil || !token.Valid {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
claims, ok := token.Claims.(*JWTClaims)
if !ok {
c.AbortWithStatus(http.StatusUnauthorized)
return
}
c.Set("user_id", claims.UserID)
c.Next()
}
}
安全考虑
- 保护Refresh Token:由于Refresh Token具有长期有效性,应妥善存储,避免在前端存储,建议存储在服务器端或使用HTTP-only Cookies。
- 传输安全:所有涉及Token的请求都应通过HTTPS进行,防止中间人攻击。
- 限制刷新次数:可以设置Refresh Token的使用次数限制,进一步增强安全性。
- 定期更新Refresh Token:即使Refresh Token有效期较长,也应定期更新,避免长期固定不变。
通过以上实现,我们可以在Go语言中高效地处理JWT Token的刷新逻辑,既保证了用户认证的安全性,又提升了用户体验。希望这些代码示例能帮助你更好地理解和实现JWT Token刷新功能。
热门推荐
安徽改名最成功的大学PK最失败的大学:谁更胜一筹?
正念冥想如何影响我们的身体健康?
柑橘黄酮片的作用与功效
锂价尚在“冰谷”,锂企纷纷降本、延长产业链,等待下一个“黎明”
电脑快捷键怎么设置?记好这3个设置方法!
乌龟、王八、甲鱼和鳖,究竟有何区别?钓鱼人首先要分清!
《红楼梦》的现世意义
事故车如何鉴定和评估?
轻松开启IPv6:设备支持与系统设置全攻略
新城市志|上海又将新添高铁站,“八纵八横”落下关键一子
人工智能在艺术创作中的应用与影响:探索技术革新与创意融合的全景解析
巨门星在财帛宫的意义详解 巨门星守财帛宫分析
基于R语言群体遗传学:超显性与次显性
平陆运河:700亿投资背后的价值与广西发展新篇
揭秘多面蒋介石:不为人知的冷知识
限制刑事责任能力的精神病人犯罪,处罚究竟如何判定?
Discovery探索频道连播五部中国主题纪录片,讲了什么故事?
空气净化器使用后空气质量无变化的原因是什么?
成长的励志名言(精选80句)
羊大师分析,羊奶养生智慧
暑假近视高发期,这份防控攻略请收好
帮推车、“搭把手”……青岛这些“热心肠”做的好事藏不住了!
无论关系多亲密,这三种人最好敬而远之,否则代价惨重
坐月子能不能吃炸鸡
一过性血糖高的原因、检测与处理建议
存款余额与财务健康的关系
中老年人早餐吃啥算优质?每天容易缺乏哪种营养素?
道家与儒家思想的对比与融合
万字实操指南:如何在超大规模集群下训练大语言模型
打击野生动植物非法贸易部际联席会议召开