英文:
How to iterate over the decoded claims of a Jwt token in Go?
问题
我正在参考这篇帖子(https://stackoverflow.com/questions/45405626/how-to-decode-a-jwt-token-in-go)来获取Jwt令牌的声明字段。以下是我根据这篇帖子使用的代码:
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
})
// ... 错误处理
// 处理解码后的声明
for key, val := range claims {
fmt.Printf("Key: %v, value: %v\n", key, val)
}
我成功获取了这些声明及其值。然而,在这个Jwt令牌中,有一个称为'scope'的声明字段,它具有字符串数组值,如'['openId','username','email']。
现在我想使用循环遍历这些值。
for _, v := range claims["scope"] {
fmt.Println(v)
}
然而,当我尝试循环遍历这个claims["scope"]时,我收到了一个错误消息:
"cannot range over claims["scope"] (type interface {})"
如何遍历这些claims["scope"]的值?另外,是否可以将其转换为其他形式,比如字符串数组或JSON,以便进行遍历?
谢谢。
英文:
I am referring to this post (https://stackoverflow.com/questions/45405626/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'].
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.
答案1
得分: 2
有几种方法可以处理这个问题;最简单的方法可能是让库为您解码(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)
}
如果您想坚持使用您问题中使用的方法,那么您需要使用类型断言(playground - 有关更多信息,请参阅json文档):
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.([]interface{})
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)
}
英文:
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论