package jwtx import ( "encoding/json" "errors" "time" "github.com/golang-jwt/jwt/v4" ) const ExtraKey = "extra" type JwtClaims struct { UserId int64 `json:"userId"` AgentId int64 `json:"agentId"` Platform string `json:"platform"` // 用户身份类型:0-临时用户,1-正式用户 UserType int64 `json:"userType"` // 是否代理:0-否,1-是 IsAgent int64 `json:"isAgent"` } // MapToJwtClaims 将 map[string]interface{} 转换为 JwtClaims 结构体 func MapToJwtClaims(claimsMap map[string]interface{}) (*JwtClaims, error) { // 使用JSON序列化/反序列化的方式自动转换 jsonData, err := json.Marshal(claimsMap) if err != nil { return nil, errors.New("序列化claims失败") } var claims JwtClaims if err := json.Unmarshal(jsonData, &claims); err != nil { return nil, errors.New("反序列化claims失败") } return &claims, nil } // GenerateJwtToken 生成JWT token func GenerateJwtToken(claims JwtClaims, secret string, expire int64) (string, error) { now := time.Now().Unix() // 将 claims 结构体转换为 map[string]interface{} claimsBytes, err := json.Marshal(claims) if err != nil { return "", err } var claimsMap map[string]interface{} if err := json.Unmarshal(claimsBytes, &claimsMap); err != nil { return "", err } jwtClaims := jwt.MapClaims{ "exp": now + expire, "iat": now, "userId": claims.UserId, ExtraKey: claimsMap, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims) return token.SignedString([]byte(secret)) } func ParseJwtToken(tokenStr string, secret string) (*JwtClaims, error) { token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) { return []byte(secret), nil }) if err != nil || !token.Valid { return nil, errors.New("invalid JWT") } claims, ok := token.Claims.(jwt.MapClaims) if !ok || !token.Valid { return nil, errors.New("invalid JWT claims") } extraInfo, exists := claims[ExtraKey] if !exists { return nil, errors.New("extra not found in JWT") } // 尝试直接断言为 JwtClaims 结构体 if jwtClaims, ok := extraInfo.(JwtClaims); ok { return &jwtClaims, nil } // 尝试从 map[string]interface{} 中解析 if claimsMap, ok := extraInfo.(map[string]interface{}); ok { return MapToJwtClaims(claimsMap) } return nil, errors.New("unsupported extra type in JWT") }