首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当在循环中创建JWT令牌时,在jwt-go中获取相同的令牌。

当在循环中创建JWT令牌时,在jwt-go中获取相同的令牌。
EN

Stack Overflow用户
提问于 2019-08-31 06:08:41
回答 2查看 881关注 0票数 2

我正在使用jwt库创建jwt令牌。后来编写了一个脚本来加载测试。当我发送多个并发请求得到相同的令牌时,我注意到了。为了更多地检查这一点,我在循环内部创建了令牌,结果是相同的。

我使用的库是https://github.com/dgrijalva/jwt-go,go版本是1.12.9。

代码语言:javascript
复制
expirationTime := time.Now().Add(time.Duration(60) * time.Minute)

    for i := 1; i < 5; i++ {
        claims := &jwt.StandardClaims{
            ExpiresAt: expirationTime.Unix(),
            Issuer:"telescope",
        }
        _token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
        var jwtKey = []byte("secret_key")
        auth_token, _ := _token.SignedString(jwtKey)
        fmt.Println(auth_token)
    }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-31 10:34:38

JWT包含三个部分:大部分是固定的头、一组声明和一个签名。RFC 7519有实际的细节。如果标头是固定的,两个令牌之间的声明是相同的,那么签名也是相同的,您可以很容易地得到重复的令牌。这两个时间戳声明"iat“和"exp”只处于第二个粒度,因此如果在同一秒钟内使用代码发出多个标记,则会得到相同的结果(即使将expirationTime计算移到循环中)。

jwt库将在StandardClaims中列出的RFC 7519§4.1导出为一个结构,这就是您在代码中使用的结构。深入研究库代码,这里没有什么特别微妙的东西:StandardClaims使用普通的"encoding/json"注释,然后当令牌被写出来时,声明是JSON编码的,然后是base64 64编码的。。因此,给定一个固定的输入,你将得到一个固定的输出。

如果您希望每个令牌在某种程度上是“不同的”,标准的"jti“索赔是提供唯一ID的地方,这不是StandardClaims的一部分,因此您需要创建包含它的自定义声明类型。

代码语言:javascript
复制
type UniqueClaims struct {
    jwt.StandardClaims
    TokenId string `json:"jti,omitempty"`
}

然后,当您创建索赔结构时,需要自己生成一个唯一的TokenId

代码语言:javascript
复制
import (
    "crypto/rand"
    "encoding/base64"
)

bits := make([]byte, 12)
_, err := rand.Read(bits)
if err != nil {
    panic(err)
}
claims := UniqueClaims{
    StandardClaims: jwt.StandardClaims{...},
    TokenId: base64.StdEncoding.EncodeToString(bits),
}

https://play.golang.org/p/zDnkamwsCi-有一个完整的示例;每次运行它,您都会得到一个不同的令牌,即使您在同一秒钟内多次运行它。您可以手工对令牌的中间部分进行base64解码,以查看声明,也可以使用像https://jwt.io/调试器这样的工具对其进行解码。

票数 4
EN

Stack Overflow用户

发布于 2019-08-31 09:28:39

我改变了你的代码:

  • 循环中expirationTime的移动计算
  • 在循环的每一步增加1秒的延迟 对于I := 1,I< 5;i++ { expirationTime := time.Now().Add(time.Duration(60) * time.Minute)索赔:= &jwt.StandardClaims{ ExpiresAt: expirationTime.Unix(),Issuer:“望远镜”,} _token := jwt.NewWithClaims(jwt.SigningMethodHS256,索赔) var jwtKey =[]字节(“secret_key”)jwtKey,- := _token.SignedString(jwtKey) fmt.Println(auth_token) time.Sleep(time.Duration(1) * time.Second) }

在这种情况下,我们得到了不同的令牌:

代码语言:javascript
复制
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjcyNDcwNDgsImlzcyI6InRlbGVzY29wZSJ9.G7wV-zsCYjysLEdgYAq_92JGDPsgqqOz9lZxdh5gcX8
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjcyNDcwNDksImlzcyI6InRlbGVzY29wZSJ9.yPNV20EN3XJbGiHhe-wGTdiluJyVHXj3nIqEsfwDZ0Q
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjcyNDcwNTAsImlzcyI6InRlbGVzY29wZSJ9.W3xFXEiVwh8xK47dZinpXFpKuvUl1LFUAiaLZZzZ2L0
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjcyNDcwNTEsImlzcyI6InRlbGVzY29wZSJ9.wYUbzdXm_VQGdFH9RynAVVouW9h6KI1tHRFJ0Y322i4

对不起,我不是JWT的大专家,我希望有人从RFC的角度来解释我们的行为。

我想要不同的代币。同一个人用不同的浏览器登录到系统。所以我想保留很多代币。

它是同一个用户,我们可以给他同样的令牌。如果我们想给它另一个版本,我们需要撤销以前的版本,或者客户端必须刷新它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57735602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档