dtlc84438 2018-09-22 19:39
浏览 997
已采纳

dgrijalva / jwt-go可以对MapClaims提出主张,但不能对StandardClaims提出主张吗?

I am creating the token with the following code

token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.StandardClaims{
    Subject: string(user.Id),
})

tokenString, err := token.SignedString([]byte("secret"))

and trying to parse them with the following code

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
    if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
        return nil, UnauthorizedError
    }

    return []byte("secret"), nil
})
if err != nil {
    return -1, UnauthorizedError
}

if !token.Valid {
    return -1, UnauthorizedError
}

claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
    return -1, UnauthorizedError
}

logrus.Info(claims)

Why can I not cast my claims to StandardClaims and access claims.Subject?

  • 写回答

1条回答 默认 最新

  • duanlu9970 2018-09-22 22:26
    关注

    Why can I not cast my claims to StandardClaims and access claims.Subject?

    Conceptually, this is not possible because the jwt.Parse function by default parses claims into an instance of jwt.MapClaims. This is a fundamentally different data structure to jwt.StandardClaims; there is no way the compiler can automatically convert between the two using a simple type conversion as they represent the data differently.

    Resolution

    The library provides the ParseWithClaims function, which allows you to specify your own implementer of the jwt.Claims interface for claims to be decoded into. You can pass an instance of jwt.StandardClaims. For example:

    token, err := jwt.ParseWithClaims(
        tokenString, &jwt.StandardClaims{},
        func(token *jwt.Token) (interface{}, error) {
            // ...
        },
    )
    

    If possible, the claims will be parsed and decoded into the variable token.Claims. The underlying (dynamic1) type of the value stored into this variable will be *jwt.StandardClaims. This can be used in a type assertion to recover the standard claims from the interface type:

    claims, ok := token.Claims.(*jwt.StandardClaims)
    if !ok {
        // handle type assertion failure
    }
    // do something with "claims"
    

    Let's dig into the language specification and library definition some more to provide a more rigorous assessment of this claim.

    Background understanding of package types

    jwt.MapClaims is a defined type with underlying type map[string]interface{} (code).

    jwt.StandardClaims is a defined struct type (code):

    type StandardClaims struct {
        // Field set elided for brevity, as it is unimportant to the
        // answer.
    }
    

    Both types implement the jwt.Claims interface type (definition), so is assignable to a variable of type jwt.Claims:

    type Claims interface {
        Valid() bool
    }
    

    The Token struct has a field called Claims of type jwt.Claims – any value which implements the Claims interface can be assigned to Claims.

    Type assertion definition

    The language spec specifies for a type assertion expression of the form x.(T) to be valid when T is not an interface type, the dynamic type1 of x must be identical to the type T. Here, you wish to evaluate the assertion x.(*jwt.StandardClaims); i.e. the asserted type is not an interface type.

    The code for jwt.Parse eventually calls jwt.ParseWithClaims on the default parser, passing in an instance of jwt.MapClaims for the claims destination:

    func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
        return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc)
    }
    

    so the dynamic type of the Claims field in your resulting token is of type jwt.MapClaims. This type is different (i.e. not identical) to the type jwt.StandardClaims, because user-defined types are always different from any other type except themselves. Hence, the type assertion fails.


    1Dynamic types (ref): recall in Go that interface types are fulfilled implicitly by any type which implements a super-set of the methods specified in an interface. If we define an interface of type MyInterface, the variable declaration var x MyInterface has static type (defined at compile time) MyInterface. However, at runtime, we can assign any value which implements MyInterface to x. The underlying type of the value assigned to x at any moment (the type which implements the interface) specifies the dynamic type of the variable.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器