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刷新功能。
热门推荐
正常体温的波动及其对健康状况的反映与影响分析
美国经济衰退担忧加剧,黄金维持震荡走势,ETF资金流入成关键支撑
如何选择内存条频率:性能、时序与兼容性全面解析
土豆可以放冰箱吗?是保鲜还是加速变质?
会议信息展示的最佳实践:提升沟通效果和信息传达
阳台改造全攻略:从法律依据到合规要点,详解改造过程中的法律风险
富时全球股票指数大调整,多只个股异动,有何玄机?
七普数据和联合国数据关于中国育龄女性数量的对比
五行理论也能养生?一起来看看中医五行之道!
房主和租客如何避免被坑?揭秘中介“低价引流”套路
房主和租客如何避免被坑?揭秘中介“低价引流”套路
运维团队指南:完善监控指标与优化报警机制
装饰植物有哪些,为家居环境增添自然气息
微信个性签名怎么换行
病人不能复印的病历资料
窜稀的原因和治疗
生物科技发展的伦理问题
快速拿到赔偿款怎么办
纳斯达克100指数创逾两年最大跌幅,经济担忧笼罩市场
永城特色美食:从薛湖牛肉水煎包到龙岗烧鸡
我国科学家发现抗衰老新突破:水果内的提取物可延长生存期64.2%
全球视角下的犹太力量:少数族群如何在全球政治经济中熠熠生辉?
江苏吴中被立案调查尚未有结论性意见,公司或面临投资者索赔
高血压做什么运动
山楂和它们一起煮水喝,降血压血脂,血液也干净了
老是纠结一件事想不开怎么办
美国高校的终身教授体制是如何运行的
肝胆怎么检查
南朗山徒步路线:饱览港岛南美景!黄竹坑看日落+俯望深水湾/香港仔避风塘
工业4.0和智能制造对员工技能的要求是什么?