英文:
JWT token expired but it doesnt have expiration time
问题
我正在使用golang进行简单的登录,我有一个路由用于使用golang-jwt库生成JWT令牌,但是当我尝试在中间件中验证令牌时,虽然它是有效的令牌,但它仍然告诉我令牌已过期,我不知道为什么。
这是我生成令牌的代码:
func GenerateToken(user models.User) (string, error) {
tokenBuilder := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user": user.Email,
"nombre": user.Nombre,
"apellido": user.Apellido,
"edad": fmt.Sprint(user.Edad),
"genero": user.Genero,
"rol": user.Rol,
})
tokenBuilder.Claims.(jwt.MapClaims)["exp"] = nil
tokenString, err := tokenBuilder.SignedString([]byte(os.Getenv("SECRET")))
return tokenString, err
}
tokenBuilder.Claims.(jwt.MapClaims)["exp"] = nil
是我认为可以解决问题的地方,但是没有起作用。
我的中间件代码如下:
type CustomClaims struct {
jwt.StandardClaims
}
func JWTMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
authHeader := c.Get("Authorization")
if authHeader == "" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"message": "No Auth token",
})
}
tokenString := authHeader[7:] // "Bearer "
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(os.Getenv("SECRET")), nil
})
if err != nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"message": "Invalid token",
})
}
// 检查是否过期
claims, ok := token.Claims.(*CustomClaims)
if !ok || !token.Valid {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"message": "Invalid or expired",
})
}
// 检查令牌过期时间
if claims.ExpiresAt < time.Now().Unix() {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"message": "Expired token",
})
}
return c.Next()
}
}
我真的不知道我的生成的令牌是否正确,或者我的中间件是否正确,在这个中间件中,我尝试捕获没有过期时间的令牌,我刚开始学习golang,我进行了调查,但是我还是不明白,这个令牌可以与库创建的中间件一起使用,但是我想要自己的中间件用于不同的目的。谢谢,祝你有愉快的一天,希望我表达清楚。
英文:
I'm working in a simple login with golang i have a route that generates a token jwt with library golang-jwt but when i try to verify the token in a middleware, yes it is a valid token but it keep telling me that is expired, i don't know why
this is my code for generate the token:
func GenerateToken(user models.User) (string, error) {
tokenBuilder := jwt.NewWithClaims(jwt.SigningMethodHS256 , jwt.MapClaims{
"user":user.Email,
"nombre":user.Nombre,
"apellido":user.Apellido,
"edad":fmt.Sprint(user.Edad),
"genero":user.Genero,
"rol":user.Rol,
})
tokenBuilder.Claims.(jwt.MapClaims)["exp"] = nil
tokenString, err := tokenBuilder.SignedString([]byte(os.Getenv("SECRET")))
return tokenString,err
}
tokenBuilder.Claims.(jwt.MapClaims)["exp"] = nil
it was what i think solve the problem. but didn't work
And my middleware is this
type CustomClaims struct {
jwt.StandardClaims
}
func JWTMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
authHeader := c.Get("Authorization")
if authHeader == "" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"message": "No Auth token",
})
}
tokenString := authHeader[7:] //"Bearer "
token , err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(os.Getenv("SECRET")), nil
})
if err != nil {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"message": "Invalid token",
})
}
//Check if is expired
claims, ok := token.Claims.(*CustomClaims)
if !ok || !token.Valid {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"message": "Invalid or expired",
})
}
// Check token expiration time
if claims.ExpiresAt < time.Now().Unix() {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
"message": "Expired token",
})
}
return c.Next()
}
}
I don't really know if my generated token is right or my middleware is right, in this middleware i try to catch tokens even if this doesn't have expiration time, I'm starting in golang, i investigated but im out, this token work with the middleware created by library but i want mines for different purposes. Thank you and good day i hope i have been clear
I try tokenBuilder.Claims.(jwt.MapClaims)["exp"] = nil
and in my tokenGeneration make a new claim like this exp:0
答案1
得分: 2
如果您不设置exp
,那么StandardClaims.ExpiresAt
将采用其默认值(int64
类型,即0
),因此claims.ExpiresAt < time.Now().Unix()
将为true
(time.Now().Unix()
将大于0
!)。如果您真的想这样做,那么可以添加一个检查0
的条件,例如:
if claims.ExpiresAt != 0 && claims.ExpiresAt < time.Now().Unix() {
值得注意的是,ParseWithClaims
会验证exp
(所以您实际上不需要验证!)。请注意,它会调用Valid
,因此"如果令牌中的任何声明都不存在,仍将被视为有效声明"。
更好的选择是设置一个有效的过期时间...
另外,创建一个Minimal, Reproducible, Example,例如这个,可能会让您得出这个结论(如果没有让您的问题更简单)。
英文:
If you don't set exp
then StandardClaims.ExpiresAt
will be it's default value (int64
so 0
) and, as such, claims.ExpiresAt < time.Now().Unix()
will be true
(time.Now().Unix()
will be greater than 0
!). If you really want to do this then add a check for 0
e.g.
if claims.ExpiresAt != 0 && claims.ExpiresAt < time.Now().Unix() {
It's worth noting that ParseWithClaims
verifies exp
(so you don't really need to!). Note that it will call Valid
so "if any of the above claims are not in the token, it will still be considered a valid claim.".
A better option would be to set a valid expiry...
As a further note creating a Minimal, Reproducible, Example such as this would probably have led you to this conclusion (and if not made your question simpler).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论