简体   繁体   English

解析 jwt 令牌时验证的 JWT 密钥在哪里?

[英]Where is the JWT secret key validated when parsing a jwt token?

I'm reading the example folder for JWT i'm a bit unsure how things work for validating the token.我正在阅读 JWT 的示例文件夹,我有点不确定验证令牌的工作原理。

func ExampleNewWithClaims_customClaimsType() {
    mySigningKey := []byte("AllYourBase")

    type MyCustomClaims struct {
        Foo string `json:"foo"`
        jwt.StandardClaims
    }

    // Create the Claims
    claims := MyCustomClaims{
        "bar",
        jwt.StandardClaims{
            ExpiresAt: 15000,
            Issuer:    "test",
        },
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    ss, err := token.SignedString(mySigningKey)
    fmt.Printf("%v %v", ss, err)
    //Output: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c <nil>
}

Here it's straight forward and the token is being signed here token.SignedString(mySigningKey) using "mySigningKey"这里很简单,令牌在这里被签名token.SignedString(mySigningKey)使用“mySigningKey”

Now there unparsing is much less clear for me:现在对我来说,反解析不太清楚:

func ExampleParseWithClaims_customClaimsType() {
    tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c"

    type MyCustomClaims struct {
        Foo string `json:"foo"`
        jwt.StandardClaims
    }

    // sample token is expired.  override time so it parses as valid
    at(time.Unix(0, 0), func() {
        token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
            return []byte("AllYourBase"), nil
        })

        if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
            fmt.Printf("%v %v", claims.Foo, claims.StandardClaims.ExpiresAt)
        } else {
            fmt.Println(err)
        }
    })

    // Output: bar 15000
}

Is order to validate that the signature of the token string given back by the client is valid would you need to为了验证客户端返回的令牌字符串的签名是否有效,您需要

  • decode the claim ( done in &MyCustomClaims{} )解码声明(在 &MyCustomClaims{} 中完成)
  • validate that the signature part of the decoded claim is valid against the " pub key included in the token" using token.Valid.使用 token.Valid 验证解码声明的签名部分是否对“令牌中包含的 pub 密钥”有效。

But the example is just decoding the key and by " magic " the return is the secret/signing key?但是这个例子只是解码密钥,通过“魔法返回的是密钥/签名密钥?

It doesn't make sense to me at all.这对我来说根本没有意义。 Also returning a valid claim for a public key is useless as it could have been done by any private key.同样返回对公钥的有效声明是没有用的,因为它可以由任何私钥完成。

What am i missing?我错过了什么?

Validation is not done by the public key included in the token.验证不是由令牌中包含的公钥完成的。

HS256 is symmetric, so whatever key you used to sign the token, you have to use the same key to validate the signature, and that's what's happening. HS256 是对称的,因此无论您使用什么密钥来签署令牌,都必须使用相同的密钥来验证签名,这就是正在发生的事情。 The function passed to ParseWithClaims is returning the same key used to sign the token.传递给ParseWithClaims的 function 返回用于签署令牌的相同密钥。

If an asymmetric signing algorithm was used, you'd use the private key to sign the token, and then the public key to validate it, and that nested function would have to return the public key so that ParseWithClaims can validate it.如果使用非对称签名算法,您将使用私钥对令牌进行签名,然后使用公钥对其进行验证,并且嵌套的 function 必须返回公钥,以便ParseWithClaims可以对其进行验证。

It sounds like the part that confused you is:听起来让您感到困惑的部分是:

jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
            return []byte("AllYourBase"), nil
        })

The nested function passed to ParseWithClaims is supposed to inspect the token passed, and return the correct key that can be used to verify the signature.传递给ParseWithClaims的嵌套 function 应该检查传递的令牌,并返回可用于验证签名的正确密钥。 For HS256, it is the same as the key used to sign it.对于 HS256,它与用于签名的密钥相同。 For RSxxx, it'd be the public key, and which public key it should return can be retrieved from the token passed in. It usually contains a public key id so you can select the correct key.对于 RSxxx,它将是公钥,它应该返回的公钥可以从传入的令牌中检索。它通常包含一个公钥 id,因此您可以 select 正确的密钥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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