fully working refresh tokens. No more expiring :)

This commit is contained in:
2025-09-21 15:43:14 +01:00
parent a3345afbfa
commit 3015d7bac2
8 changed files with 1142 additions and 842 deletions

View File

@@ -1,7 +1,6 @@
package middleware
import (
"encoding/json"
"errors"
"time"
@@ -19,7 +18,7 @@ const (
type JwtClaims struct {
UserID string
Type JwtType
Expire time.Time
Expiry time.Time
}
type JwtManager struct {
@@ -34,7 +33,7 @@ func (jm *JwtManager) createToken(claims JwtClaims) *jwt.Token {
return jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"UserID": claims.UserID,
"Type": claims.Type,
"Expire": claims.Expire,
"exp": claims.Expiry.Unix(),
})
}
@@ -42,7 +41,7 @@ func (jm *JwtManager) CreateRefreshToken(userId uuid.UUID) string {
token := jm.createToken(JwtClaims{
UserID: userId.String(),
Type: Refresh,
Expire: time.Now().Add(time.Hour * 24 * 30),
Expiry: time.Now().Add(time.Hour * 24 * 30),
})
tokenString, err := token.SignedString(jm.secret)
@@ -57,7 +56,7 @@ func (jm *JwtManager) CreateAccessToken(userId uuid.UUID) string {
token := jm.createToken(JwtClaims{
UserID: userId.String(),
Type: Access,
Expire: time.Now().Add(time.Minute),
Expiry: time.Now().Add(time.Minute),
})
tokenString, err := token.SignedString(jm.secret)
@@ -79,7 +78,7 @@ func (jm *JwtManager) GetUserIdFromAccess(accessToken string) (uuid.UUID, error)
return uuid.Nil, err
}
// Check if token is valid (including expiry check)
// Check if token is valid (JWT library validates exp claim automatically)
if !token.Valid {
return uuid.Nil, NotValidToken
}
@@ -90,27 +89,34 @@ func (jm *JwtManager) GetUserIdFromAccess(accessToken string) (uuid.UUID, error)
return uuid.Nil, NotValidToken
}
// Additional explicit expiry check
expireClaim, ok := claims["Expire"]
if !ok {
userId, err := uuid.Parse(claims["UserID"].(string))
if err != nil {
return uuid.Nil, NotValidToken
}
var expireTime time.Time
switch exp := expireClaim.(type) {
case float64:
expireTime = time.Unix(int64(exp), 0)
case json.Number:
expInt, err := exp.Int64()
if err != nil {
return uuid.Nil, NotValidToken
}
expireTime = time.Unix(expInt, 0)
default:
return uuid.Nil, NotValidToken
}
return userId, nil
} else {
return uuid.Nil, NotValidToken
}
}
if time.Now().After(expireTime) {
func (jm *JwtManager) GetUserIdFromRefresh(refreshToken string) (uuid.UUID, error) {
token, err := jwt.Parse(refreshToken, func(token *jwt.Token) (any, error) {
return jm.secret, nil
}, jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Alg()}))
if err != nil {
return uuid.Nil, err
}
// Check if token is valid (JWT library validates exp claim automatically)
if !token.Valid {
return uuid.Nil, NotValidToken
}
if claims, ok := token.Claims.(jwt.MapClaims); ok {
tokenType, ok := claims["Type"]
if !ok || tokenType.(string) != "refresh" {
return uuid.Nil, NotValidToken
}