如何在 Go 中解码 JWT 令牌?

新手上路,请多包涵

我目前正在开发一个 Go 应用程序。我从客户端收到一个 JWT 令牌,我需要解码该令牌并获取相关信息:用户、名称等。

我正在检查可用于处理 JWT 令牌的库,结果是 dgrijalva/jwt-go ,但我看不出如何以简单的方式实现我的目标。

我有令牌,我需要将信息解码为地图或至少是 json。我该怎么做?

原文由 Sredny M Casanova 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

函数 jwt.ParseWithClaims 接受接口 jwt.Claims 作为第二个参数。除了基于结构的自定义声明,该包还提供 map 基于声明,即 jwt.MapClaims 。因此,您可以简单地将令牌解码为 MapClaims ,例如

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)
}

原文由 putu 发布,翻译遵循 CC BY-SA 3.0 许可协议

免责声明:我不隶属于图书馆。我只是一个用户,觉得有用,愿意分享。

现在是 2019 年。我想推荐一个 替代库,它使用 JWS 和/或 JWE 在 JWT 上做得很好。

以下是有关如何使用该库的几个示例:

 import (
    "gopkg.in/square/go-jose.v2/jwt"
    "gopkg.in/square/go-jose.v2"
)
...

var claims map[string]interface{} // generic map to store parsed token

// decode JWT token without verifying the signature
token, _ := jwt.ParseSigned(tokenString)
_ = token.UnsafeClaimsWithoutVerification(&claims)

// decode JWT token and verify signature using JSON Web Keyset
token, _ := jwt.ParseSigned(tokenString)
jwks := &jose.JSONWebKeySet { // normally you can obtain this from an endpoint exposed by authorization server
            Keys: []jose.JSONWebKey { // just an example
                {
                    Key: publicKey,
                    Algorithm: jose.RS256, // should be the same as in the JWT token header
                    KeyID: "kid", // should be the same as in the JWT token header
                },
            },
        }
_ = jwt.Claims(jwks, &claims)

请注意, claims 可以是包含默认 JWT 字段以及令牌内自定义字段的结构,例如:

 import (
    "github.com/mitchellh/mapstructure"
    "gopkg.in/square/go-jose.v2/jwt"
)
...
type CustomClaims struct {
    *jwt.Claims
    // additional claims apart from standard claims
    extra map[string]interface{}
}

func (cc *CustomClaims) UnmarshalJSON(b []byte) error {
    var rawClaims map[string]interface{}
    if err := json.Unmarshal(b, &rawClaims); err != nil {
        return nil
    }
    var claims jwt.Claims
    var decoderResult mapstructure.Metadata
    decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
        Result:   &claims,
        Metadata: &decoderResult,
        TagName:  "json",
    })
    if err != nil {
        return err
    }
    if err := decoder.Decode(rawClaims); err != nil {
        return err
    }
    cc.Claims = &claims
    cc.extra = make(map[string]interface{})
    for _, k := range decoderResult.Unused {
        cc.extra[k] = rawClaims[k]
    }
    return nil
}

我还构建 了一个命令行工具,使用该 执行各种编码/解码活动。它也可能是有关库用法的有用参考。

原文由 trung 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题