package middleware import ( "app/commons/config" "app/commons/core/redisclient" "context" "errors" "fmt" "github.com/golang-jwt/jwt/v5" "strings" "time" ) type Member struct { ID int64 //Address string OpenId string Uid string } // Secret key used to sign the JWT token (In production, use environment variables to keep it secure) var jwtSecretByte = []byte("magic.node.secret.20251212") var jwtExpireDuration = int64(24) // in seconds var jwtIssuer = "issuer" var jwtConf *config.JWT func conf() *config.JWT { if jwtConf == nil { jwtConf = config.EnvConf().JWT } if jwtConf.SigningKey != "" { jwtSecretByte = []byte(jwtConf.SigningKey) } if jwtConf.ExpiresTime > 0 { jwtExpireDuration = jwtConf.ExpiresTime } if jwtConf.Issuer != "" { jwtIssuer = jwtConf.Issuer } //core.Log.Infof("Issuer:%s ExpiresTime:%dh SigningKey:%s", jwtIssuer, jwtExpireDuration, jwtSecretByte) return jwtConf } // MyClaims 定义了JWT中的自定义声明 // // Address string `json:"address"` type MyClaims struct { UserID int64 `json:"userId"` OpenId string `json:"openId"` Uid string `json:"uid"` jwt.RegisteredClaims } // GenerateJWT 根据用户信息生成JWT func GenerateJWT(user Member) (string, error) { if jwtConf == nil { conf() } // 设置JWT的过期时间 d := time.Duration(jwtExpireDuration) * time.Hour expirationTime := time.Now().Add(d) // 创建JWT的声明 claims := MyClaims{ UserID: user.ID, OpenId: user.OpenId, Uid: user.Uid, RegisteredClaims: jwt.RegisteredClaims{ ID: fmt.Sprintf("%d", user.ID), // 设置ID ExpiresAt: jwt.NewNumericDate(expirationTime), // 设置过期时间 Issuer: jwtIssuer, // 设置签发者 }, } // 使用HS256算法签署JWT token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // 生成并返回签名后的JWT字符串 tokenString, err := token.SignedString(jwtSecretByte) if err != nil { return "", err } return tokenString, nil } // ParseJWT 解析和验证JWT func ParseJWT(tokenString string) (*MyClaims, error) { if jwtConf == nil { conf() } // 定义一个空的声明对象 claims := &MyClaims{} // 去掉 "Bearer " 部分 tokenString = strings.TrimPrefix(tokenString, "Bearer ") // 解析JWT token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) { // 验证签名算法 if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, errors.New("unexpected signing method") } return jwtSecretByte, nil }) if err != nil || !token.Valid { return nil, errors.New("invalid token") } return claims, nil } // SetUserCurrentToken 设置用户当前有效token func SetUserCurrentToken(userID int64, tokenString string, expiration time.Duration) error { tokenString = strings.TrimPrefix(tokenString, "Bearer ") key := fmt.Sprintf("user_current_token:%d", userID) return redisclient.DefaultClient().Set(context.Background(), key, tokenString, expiration).Err() } // IsCurrentValidToken 检查token是否为用户当前有效token func IsCurrentValidToken(userID int64, tokenString string) bool { tokenString = strings.TrimPrefix(tokenString, "Bearer ") key := fmt.Sprintf("user_current_token:%d", userID) currentToken, err := redisclient.DefaultClient().Get(context.Background(), key).Result() if err != nil { return false // 如果获取失败,说明没有有效token或已过期 } return currentToken == tokenString // 检查是否为当前有效token }