Golang使用jwx/jwt解析JWT嵌套结构数据报错求助
解决
github.com/lestrrat-go/jwx/jwt解析JWT嵌套结构的问题 你遇到的核心问题是:jwt.Parse解析后,复杂字段(对象、数组)会被转为通用的interface{}类型(比如map[string]interface{}、[]interface{}),无法直接通过类型断言转换为自定义结构体。下面提供两种可行的解决思路:
方法一:JSON序列化反序列化(推荐)
通过将解析出的interface{}序列化为JSON字节,再反序列到自定义结构体,利用JSON标签自动映射字段:
import ( "encoding/json" "fmt" "strings" "github.com/lestrrat-go/jwx/jwt" ) func parseJWT(tokenRaw string) (*Pds, error) { reader := strings.NewReader(tokenRaw) token, err := jwt.Parse(reader) if err != nil { return nil, err } // 定义与JWT结构匹配的结构体 type PdsrStruct struct { Comp string `json:"comp"` Duration int `json:"dur"` Unit string `json:"u"` Res string `json:"res"` } type Pds struct { R []PdsrStruct `json:"r"` } var pds Pds ret, found := token.Get("pds") if !found { return nil, fmt.Errorf("pds field not found in JWT") } // 将interface{}转为JSON字节 jsonBytes, err := json.Marshal(ret) if err != nil { return nil, fmt.Errorf("marshal pds failed: %w", err) } // 反序列到自定义结构体 if err := json.Unmarshal(jsonBytes, &pds); err != nil { return nil, fmt.Errorf("unmarshal pds failed: %w", err) } return &pds, nil }
方法二:手动类型断言转换
直接对解析出的interface{}进行逐层类型断言,手动映射字段(适合需要更精细控制的场景):
import ( "fmt" "strings" "github.com/lestrrat-go/jwx/jwt" ) func parseJWT(tokenRaw string) (*Pds, error) { reader := strings.NewReader(tokenRaw) token, err := jwt.Parse(reader) if err != nil { return nil, err } type PdsrStruct struct { Comp string Duration int Unit string Res string } type Pds struct { R []PdsrStruct } var pds Pds ret, found := token.Get("pds") if !found { return nil, fmt.Errorf("pds field not found in JWT") } // 断言pds为map类型 pdsMap, ok := ret.(map[string]interface{}) if !ok { return nil, fmt.Errorf("pds is not a valid map") } // 断言r字段为slice类型 rSlice, ok := pdsMap["r"].([]interface{}) if !ok { return nil, fmt.Errorf("r field is not a valid slice") } // 遍历slice,逐个转换为结构体 for _, item := range rSlice { itemMap, ok := item.(map[string]interface{}) if !ok { continue // 或根据业务需求返回错误 } // 注意:JWT中数字类型解析后默认是float64,需转换为int dur, ok := itemMap["dur"].(float64) if !ok { return nil, fmt.Errorf("invalid duration value") } rs := PdsrStruct{ Comp: itemMap["comp"].(string), Duration: int(dur), Unit: itemMap["u"].(string), Res: itemMap["res"].(string), } pds.R = append(pds.R, rs) } return &pds, nil }
注意事项
- 结构体字段的JSON标签必须与JWT中的字段名完全匹配(比如
json:"dur"对应JWT里的dur字段)。 - JWT中的数字类型会被解析为
float64,手动转换时需要注意类型转换的安全性,避免panic。 - 两种方法都需要做好错误处理,避免类型断言失败导致程序崩溃。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

