我正在使用jwt库创建jwt令牌。后来编写了一个脚本来加载测试。当我发送多个并发请求得到相同的令牌时,我注意到了。为了更多地检查这一点,我在循环内部创建了令牌,结果是相同的。
我使用的库是https://github.com/dgrijalva/jwt-go,go版本是1.12.9。
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)
}发布于 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的一部分,因此您需要创建包含它的自定义声明类型。
type UniqueClaims struct {
jwt.StandardClaims
TokenId string `json:"jti,omitempty"`
}然后,当您创建索赔结构时,需要自己生成一个唯一的TokenId。
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/调试器这样的工具对其进行解码。
发布于 2019-08-31 09:28:39
我改变了你的代码:
expirationTime的移动计算在这种情况下,我们得到了不同的令牌:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjcyNDcwNDgsImlzcyI6InRlbGVzY29wZSJ9.G7wV-zsCYjysLEdgYAq_92JGDPsgqqOz9lZxdh5gcX8
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjcyNDcwNDksImlzcyI6InRlbGVzY29wZSJ9.yPNV20EN3XJbGiHhe-wGTdiluJyVHXj3nIqEsfwDZ0Q
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjcyNDcwNTAsImlzcyI6InRlbGVzY29wZSJ9.W3xFXEiVwh8xK47dZinpXFpKuvUl1LFUAiaLZZzZ2L0
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NjcyNDcwNTEsImlzcyI6InRlbGVzY29wZSJ9.wYUbzdXm_VQGdFH9RynAVVouW9h6KI1tHRFJ0Y322i4对不起,我不是JWT的大专家,我希望有人从RFC的角度来解释我们的行为。
我想要不同的代币。同一个人用不同的浏览器登录到系统。所以我想保留很多代币。
它是同一个用户,我们可以给他同样的令牌。如果我们想给它另一个版本,我们需要撤销以前的版本,或者客户端必须刷新它。
https://stackoverflow.com/questions/57735602
复制相似问题