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刷新功能。
热门推荐
日本留学JASSO奖学金是什么?金额有多少?
动动舌头可以减缓大脑萎缩,试试这3个练习方法!
银屑病动物模型:从发病机制到研究应用
购买假冒伪劣产品欺骗消费者向什么部门投诉
《勇者斗恶龙8》二十周年回顾:重温经典RPG的辉煌岁月
如何理性选择货币基金的投资方式?这些投资方式的特点有哪些?
手机停机后能否收到短信?详解停机状态下的短信接收规则
牛结节病的症状与治疗方法详解
探索化学元素周期表
巴洛克艺术的代表人物及其杰作
各类毕业论文参考文献数量要求及格式规范
无土栽培技术应对极端环境的探索与挑战
二手车交易必知:车辆违章记录方法查询
借问酒家何处有:追溯中国的酒文化及其现代社会意义
eCryptfs-你的下一个加密系统,何必是bitlocker
慢性鼻窦炎急性发作期用什么抗生素
武汉长春观:江南第一大福地
电压力锅做蛋糕要多久
孩子睡前喊“饿”,要不要吃夜宵?
矿源黄腐酸钾:最佳混配效果的秘密武器
Excel中插入圆形并进行填充的详细步骤
幼儿园户外活动器械:功能、选购与使用指南
角色扮演游戏给孩子带来的好处
重大调整!2025年中国十大油气田出炉!
重大调整!2025年中国十大油气田出炉!
绿茵场的数字魔法:FM系列是怎么成为“最好的足球模拟游戏”的?
如何搜数据库的顶级期刊
夏日必备!冰粉这样做,清凉解暑,简单到零失败!
孤独的银行家宋子文,掌管财权数年,却被沦为妹夫的军需官
橄榄的药用价值和功效与作用以及营养价值