英文:
Invalid memory address or nil pointer dereference verifying jwt expiration time
问题
我正在使用golang和jwt令牌进行登录,到目前为止一切都很好,它检查令牌的剩余时间,如果没有令牌,它会发送一条消息。但是我有两个问题,如果令牌无效或过期时间已过,则显示以下错误:
导致错误的代码行是:
claims := token.Claims.(*jwtCustomClaims)
我的jwtCustomClaims变量如下所示:
type jwtCustomClaims struct {
User string `json:"email"`
Nombre string `json:"nombre"`
Apellido string `json:"apellido"`
Edad int `json:"edad"`
Genero string `json:"genero"`
Rol string `json:"rol"`
jwt.StandardClaims
}
使用此结构体还生成了令牌,检查令牌的完整函数如下:
func ValidateToken(tokenString string, secretKey string, c *fiber.Ctx) (*jwt.Token, error) {
token, err := jwt.ParseWithClaims(tokenString, &jwtCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
if err != nil {
if err == jwt.ErrSignatureInvalid {
return nil, err
}
return nil, c.JSON(fiber.Map{
"message": "Unauthorized",
"code": 400,
})
}
_, ok := token.Claims.(*jwtCustomClaims)
if !ok || !token.Valid {
return nil, c.JSON(fiber.Map{
"message": "Unauthorized",
"code": 400,
})
}
return token, nil
}
func TokenMiddleware(c *fiber.Ctx) error {
tokenString := c.Get("Authorization")
if tokenString == "" {
return c.JSON(fiber.Map{
"message": "No token",
"code": 400,
})
}
// 从头部中分离出令牌 "Bearer"
tokenString = strings.ReplaceAll(tokenString, "Bearer ", "")
token, err := ValidateToken(tokenString, os.Getenv("SECRET"), c)
if err != nil {
return err
}
claims := token.Claims.(*jwtCustomClaims)
expiresIn := time.Until(time.Unix(claims.ExpiresAt, 0))
if expiresIn > 0 {
return c.JSON(fiber.Map{
"message": "Token is valid",
"expires_in": expiresIn.String(),
"is_expired": false,
})
//return c.Next()
} else {
return c.JSON(fiber.Map{
"message": "Token is valid but expired",
"expires_in": 0,
"is_expired": true,
})
}
}
为了检查它是否验证令牌,我只是尝试放入另一种类型的令牌,来自另一个项目,并将其写错以进行测试,但它会发送一个控制台错误。至于过期时间,我在网上查看了错误并找到了一个解决方法,将其写成if claims == nil
,但它没有起作用,我不知道还能做什么。
英文:
I'm working on a login with golang using jwt token, everything so far is god, it checks what time is left on the token, if there is no token it send a message
But I have 2 problems, if the token is invalid or the expiration time is out it shows this error:
And the line that carry the error is this
claims := token.Claims.(*jwtCustomClaims)
my jwtCustomClaims variable is this:
type jwtCustomClaims struct {
User string `json:"email"`
Nombre string `json:"nombre"`
Apellido string `json:"apellido"`
Edad int `json:"edad"`
Genero string `json:"genero"`
Rol string `json:"rol"`
jwt.StandardClaims
}
with this struct is also generated the token, and the full function to check the token is this
func ValidateToken(tokenString string, secretKey string, c *fiber.Ctx) (*jwt.Token, error) {
token, err := jwt.ParseWithClaims(tokenString, &jwtCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
if err != nil {
if err == jwt.ErrSignatureInvalid {
return nil, err
}
return nil, c.JSON(fiber.Map{
"message": "Unauthorized",
"code": 400,
})
}
_, ok := token.Claims.(*jwtCustomClaims)
if !ok || !token.Valid {
return nil, c.JSON(fiber.Map{
"message": "Unauthorized",
"code": 400,
})
}
return token, nil
}
func TokenMiddleware(c *fiber.Ctx) error {
tokenString := c.Get("Authorization")
if tokenString == "" {
return c.JSON(fiber.Map{
"message": "No token",
"code": 400,
})
}
// Separa el token del encabezado "Bearer"
tokenString = strings.ReplaceAll(tokenString, "Bearer ", "")
token, err := ValidateToken(tokenString, os.Getenv("SECRET"), c)
if err != nil {
return err
}
claims := token.Claims.(*jwtCustomClaims)
expiresIn := time.Until(time.Unix(claims.ExpiresAt, 0))
if expiresIn > 0 {
return c.JSON(fiber.Map{
"message": "Token is valid",
"expires_in": expiresIn.String(),
"is_expired": false,
})
//return c.Next()
} else {
return c.JSON(fiber.Map{
"message": "Token is valid but expired",
"expires_in": 0,
"is_expired": true,
})
}
}
To check if it validate the token i just try to put another type of token, from an other proyect and write it wrong just to test but it send a console error. And for the expiration time i look the error on the web and a solution to this is to write it like this if claims == nil
but it didn't work, I don't know what else to do
答案1
得分: 0
请测试一下:
func ValidateToken(tokenString string, secretKey string, c *fiber.Ctx) (jwtCustomClaims, error) {
var claims jwtCustomClaims
token, err := jwt.ParseWithClaims(tokenString, &claims, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
if err != nil {
if err == jwt.ErrSignatureInvalid {
return jwtCustomClaims{}, err
}
return jwtCustomClaims{}, c.JSON(fiber.Map{
"message": "未经授权",
"code": 400,
})
}
if !token.Valid {
return jwtCustomClaims{}, c.JSON(fiber.Map{
"message": "未经授权",
"code": 400,
})
}
return claims, nil
}
func TokenMiddleware(c *fiber.Ctx) error {
.
.
.
claims, err := ValidateToken(tokenString, os.Getenv("SECRET"), c)
if err != nil {
return err
}
expiresIn := time.Until(time.Unix(claims.ExpiresAt, 0))
.
.
.
}
英文:
Please test it:
func ValidateToken(tokenString string, secretKey string, c *fiber.Ctx) (jwtCustomClaims, error) {
var claims jwtCustomClaims
token, err := jwt.ParseWithClaims(tokenString, &claims, func(token *jwt.Token) (interface{}, error) {
return []byte(secretKey), nil
})
if err != nil {
if err == jwt.ErrSignatureInvalid {
return jwtCustomClaims{}, err
}
return jwtCustomClaims{}, c.JSON(fiber.Map{
"message": "Unauthorized",
"code": 400,
})
}
if !token.Valid {
return jwtCustomClaims{}, c.JSON(fiber.Map{
"message": "Unauthorized",
"code": 400,
})
}
return claims, nil
}
func TokenMiddleware(c *fiber.Ctx) error {
.
.
.
claims, err := ValidateToken(tokenString, os.Getenv("SECRET"), c)
if err != nil {
return err
}
expiresIn := time.Until(time.Unix(claims.ExpiresAt, 0))
.
.
.
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论