简体   繁体   中英

How to iterate over the decoded claims of a Jwt token in Go?

I am referring to this post ( How to decode a JWT token in Go? ) to get the claim fields of a Jwt token. Here are the code that I used based on this post:

tokenString := "<YOUR TOKEN STRING>"    
claims := jwt.MapClaims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
    return []byte("<YOUR VERIFICATION KEY>"), nil
})
// ... error handling

// do something with decoded claims
for key, val := range claims {
    fmt.Printf("Key: %v, value: %v\n", key, val)
}

I managed to get those claims and its values. However, in this Jwt token, there is a claim field called 'scope', and it has a string array values, like '['openId','username','email'].

Jwt 令牌的声明值

Now I want to iterate over these values using loop.

for _, v := range claims["scope"]{
      fmt.Println(v)
}

However, when I try to loop over this claims ["scope"], I got an error message saying that:

"cannot range over claims["scope"] (type interface {})".

How to iterate over these claims["scope"] values? Also, is it possible to convert it to other forms, like string array or json, to iterate over it?

Thanks.

There are a few ways you can handle this; the simplest is probably to let the library decode things for you ( playground )

type MyCustomClaims struct {
    Scope []string `json:"scope"`
    jwt.StandardClaims
}

claims := MyCustomClaims{}
_, err := jwt.ParseWithClaims(tokenString, &claims, func(token *jwt.Token) (interface{}, error) {
    return []byte(sharedKey), nil
})
if err != nil {
    panic(err)
}

for _, s := range claims.Scope {
    fmt.Printf("%s\n", s)
}

If you want to stick with the approach used in your question then you will need to use type assertions ( playground - see the json docs for more info on this):

var claims jwt.MapClaims
_, err := jwt.ParseWithClaims(tokenString, &claims, func(token *jwt.Token) (interface{}, error) {
    return []byte(sharedKey), nil
})
if err != nil {
    panic(err)
}

scope := claims["scope"]
if scope == nil {
    panic("no scope")
}
scopeSlc, ok := scope.([]any)
if !ok {
    panic("scope not a slice")
}

for _, s := range scopeSlc {
    sStr, ok := s.(string)
    if !ok {
        panic("slice member not a string")
    }
    fmt.Println(sStr)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM