当前位置: 首页 > 知识库问答 >
问题:

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

王声
2023-03-14

我正在阅读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>
}

这里直接使用“mySigningKey”在token.signedString(mySigningKey)中签名

现在,对我来说,未解析就不那么清楚了:

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
}

是为了验证客户端返回的令牌字符串的签名是否有效,您是否需要

  • 解码声明(在&MyCustomClaims{}中完成)
  • 使用token.valid验证解码声明的签名部分对“令牌中包含的pub密钥”是否有效。

但这个例子只是解码密钥,通过“魔术”返回的是秘密/签名密钥?

这对我来说一点意义都没有。同样,为公钥返回有效的声明也是无用的,因为任何私钥都可以这样做。

我错过了什么?

共有1个答案

于鸿博
2023-03-14

验证不是由标记中包含的公钥完成的。

HS256是对称的,所以无论您使用什么密钥来签名令牌,您都必须使用相同的密钥来验证签名,这就是所发生的事情。传递给parsewithclaims的函数返回的密钥与标记签名所用的密钥相同。

如果使用非对称签名算法,您将使用私钥对令牌进行签名,然后使用公钥对其进行验证,并且嵌套函数必须返回公钥,以便ParseWithClaims能够对其进行验证。

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

传递给parsewithclaims的嵌套函数应该检查传递的令牌,并返回可用于验证签名的正确密钥。对于HS256,它与用来签名的密钥相同。对于RSxxx,它是公钥,它应该返回的公钥可以从传入的令牌中检索。它通常包含一个公钥id,以便您可以选择正确的密钥。

 类似资料:
  • 我正在实现一个需要身份验证的REST服务。我正在使用JWT。 现在,Android应用程序在登录时发送一个请求,获得一个令牌,并且必须在每个后续请求的头中发送令牌。 我的问题是,如何存储令牌,或者我应该将其存储在哪里? 共享偏好 SQLite数据库 归档 最好的做法是什么?还是我完全错了?

  • 我目前正在使用Vapor开发Swift后端。我的iOS客户端使用新的iOS 13功能“使用Apple登录”。当用户登录时,我会得到一个身份令牌(访问令牌),这是一个由Apple签名的有效JWT令牌。这将在所有正在进行的通信中发送到服务器,以验证服务器提供的某些路由。 在服务器上,我想通过验证令牌签名来验证发送的令牌是否确实由Apple签名,并且不是由某些恶意用户专门创建的。Apple提供了一个HT

  • 我们正在使用JWT Nuget来创建和验证令牌。下面是我们用来创建令牌的代码 我的理解是,这不会加密令牌,因为我能够通过访问jwt.io解析令牌,并且能够读取内容。我想加密令牌,这样它就不应该被解析。我在JWT Nuget中找不到任何可以加密令牌的方法。 那么如何使用JWT nuget对令牌进行签名和加密呢? 编辑: 我知道JWT不需要任何加密,因为只有经过身份验证的用户才能读取令牌,这意味着,我

  • 我正在制作一个javascript客户端,它使用JWT令牌连接到Api。在服务器端没有问题,我可以创建令牌对其进行签名,然后验证签名,从而确保没有人篡改令牌。 但我如何在客户端做到这一点。我可以解码JWT令牌并查看头、负载和签名。但是如何在客户端验证签名?是否有用于此的库,如何将公钥传输到客户端? 如果我不验证签名,我怎么知道令牌没有被篡改?

  • 我在做一个全堆栈的web应用程序。我的前端由angular-cli组成,后端由node+Express构建。