【问题标题】:How to access JWT sub-claims using Go?如何使用 Go 访问 JWT 子声明?
【发布时间】:2020-07-31 13:05:51
【问题描述】:

我需要从 Go 中的 JWT 检索子声明的值。

我需要在 go 中解析(旧版)JWT,其中包含一个自定义声明“数据”,其中包含一个由一些字段(用户 ID、用户名)组成的 Json-Object,所以

{ [...standard claims]..., "data":{"id":"123", "name":"JohnDoe"} }

使用github.com/dgrijalva/jwt-go,我可以解析令牌并访问声明:

keyfunc := func(token *jwt.Token) (interface{}, error) {
    return tknkey, nil
}

tkn, err := jwt.Parse(tknStr, keyfunc)
cl, _ := tkn.Claims.(jwt.MapClaims)

这适用于标准声明,我还从“数据”声明中的 Json-Sub-Object 获取字段名称,但不是字段值(所有空字符串)。我还尝试设置与声明层次结构匹配的结构(外部和内部结构),但没有成功。

访问子声明值的方法是什么?

【问题讨论】:

    标签: go jwt jwt-go


    【解决方案1】:

    您可以通过以下步骤将jwt.MapClaims"data": map[string]string 一起使用。

    • 步骤 1.1 和 1.2 创建令牌
    • 步骤 2.1 和 2.2 解析令牌并提取子声明值。

    在下面的示例中,jwtgithub.com/dgrijalva/jwt-go。此示例的运行代码位于github.com/grokify/oauth2more/examples/jwt/main.go

    步骤 1.1:创建声明

    使用data 映射创建自定义MapClaims。添加一个自定义的data.name 属性,我们将在下面提取它。

    claims := &jwt.MapClaims{
        "iss": "issuer",
        "exp": time.Now().Add(time.Hour).Unix(),
        "data": map[string]string{
            "id":   "123",
            "name": "JohnDoe",
        },
    }
    

    步骤 1.2:创建 JWT

    在本例中,我们将使用对称密钥。

    token := jwt.NewWithClaims(
        jwt.SigningMethodHS256,
        claims)
    
    secretKey := "foobar"
    
    tokenString, err := token.SignedString([]byte(secretKey))
    

    步骤 2.1:解析令牌并将声明转换为 MapClaims

    再次使用secretKey,因为此示例使用 HS256。

    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        return []byte(secretKey), nil
    })
    
    claims := token.Claims.(jwt.MapClaims)
    

    步骤 2.2:提取自定义子声明

    data 转换为map[string]interface{} 并将data["name"] 转换为string

    data := claims["data"].(map[string]interface{})
    name := data["name"].(string)
    

    【讨论】:

    • 如果我需要更深一层怎么办? Twilio JWT 声明如下:"grants": { "identity": "user_name", "chat": {"service_sid": "ISxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} } 在这种情况下,您似乎不能使用 map[string]string 来构建声明
    • 这里的问题的答案已经完成,但使用map[string]interface{} 很容易。你想要一个例子吗?如果是这样,我可以考虑同时编辑问题和答案以使其更通用。
    • 可能会很好地演示如何深入一层。我想通了 - 你可以使用 map[string]interface{} 或只使用 jwt.MapClaims{} 这是同一件事
    猜你喜欢
    • 2020-03-31
    • 1970-01-01
    • 2016-08-11
    • 2016-04-30
    • 2021-08-06
    • 1970-01-01
    • 2015-05-08
    • 2019-10-11
    • 2019-05-24
    相关资源
    最近更新 更多