package middleware import ( "errors" "strconv" "time" "git.echol.cn/loser/Go-Web-Template/server/global" "git.echol.cn/loser/Go-Web-Template/server/model/common/response" "git.echol.cn/loser/Go-Web-Template/server/utils" "github.com/gin-gonic/gin" "github.com/golang-jwt/jwt/v5" ) // AppJWTAuth 玩家端 JWT 鉴权(仅接受 aud=GVA_APP) func AppJWTAuth() gin.HandlerFunc { return func(c *gin.Context) { token := utils.GetToken(c) if token == "" { response.NoAuth("未登录或非法访问,请登录", c) c.Abort() return } if isBlacklist(token) { response.NoAuth("您的帐户异地登陆或令牌失效", c) utils.ClearToken(c) c.Abort() return } j := utils.NewJWT() claims, err := j.ParseToken(token) if err != nil { if errors.Is(err, utils.TokenExpired) { response.NoAuth("登录已过期,请重新登录", c) utils.ClearToken(c) c.Abort() return } response.NoAuth(err.Error(), c) utils.ClearToken(c) c.Abort() return } if len(claims.Audience) == 0 || claims.Audience[0] != utils.JWTAudienceApp { response.NoAuth("令牌无效", c) utils.ClearToken(c) c.Abort() return } c.Set("claims", claims) if claims.ExpiresAt.Unix()-time.Now().Unix() < claims.BufferTime { dr, _ := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime) claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(dr)) newToken, _ := j.CreateTokenByOldToken(token, *claims) newClaims, _ := j.ParseToken(newToken) c.Header("new-token", newToken) c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt.Unix(), 10)) utils.SetToken(c, newToken, int(dr.Seconds()/60)) if global.GVA_CONFIG.System.UseMultipoint { _ = utils.SetRedisJWT(newToken, newClaims.Username) } } c.Next() if newToken, exists := c.Get("new-token"); exists { c.Header("new-token", newToken.(string)) } if newExpiresAt, exists := c.Get("new-expires-at"); exists { c.Header("new-expires-at", newExpiresAt.(string)) } } }