From f7e8fa9c754fb9ede7110a3897407758acd84da5 Mon Sep 17 00:00:00 2001 From: meandaD Date: Sun, 21 Jan 2024 22:15:22 +0100 Subject: [PATCH] Middleware: Add the logic to prolong the validity period in case that the user selected "remember me" when logging in --- tools/middlewares.go | 29 +++++++++++++++++++++++++++++ tools/session.go | 2 ++ 2 files changed, 31 insertions(+) diff --git a/tools/middlewares.go b/tools/middlewares.go index bde9a0042..b311760a7 100644 --- a/tools/middlewares.go +++ b/tools/middlewares.go @@ -6,6 +6,7 @@ import ( "net/url" "strconv" "strings" + "time" "github.com/TUM-Dev/gocast/dao" "github.com/TUM-Dev/gocast/model" @@ -15,6 +16,11 @@ import ( "github.com/golang-jwt/jwt/v4" ) +const ( + MaxTokenLifetimeWithRememberMeInDays = 180 + MinUpdateIntervalInHours = 1 +) + var templateExecutor TemplateExecutor // SetTemplateExecutor sets the templates and template executor for the middlewares to execute error pages @@ -25,6 +31,7 @@ func SetTemplateExecutor(e TemplateExecutor) { // JWTClaims are the claims contained in a session type JWTClaims struct { *jwt.RegisteredClaims + UpdatedAt *jwt.NumericDate UserID uint SamlSubjectID *string // identifier of the SAML session (if any) RememberMe bool @@ -63,6 +70,28 @@ func InitContext(daoWrapper dao.DaoWrapper) gin.HandlerFunc { return } + claims := token.Claims.(*JWTClaims) + + // in case when the user has selected "remember me" when logging in, prolong the validity of the token + // but only when the token has not been updated during the last 1 hour + if claims.RememberMe && time.Now().Sub(claims.UpdatedAt.Time).Hours() > MinUpdateIntervalInHours { + // remove jwt cookie older than MaxTokenAgeWithRefreshInDays + expiresAt := &jwt.NumericDate{time.Now().Add(time.Hour * 24 * MaxTokenAgeInDays)} + if expiresAt.Sub(claims.IssuedAt.Time).Hours() > MaxTokenLifetimeWithRememberMeInDays*24 { + c.SetCookie("jwt", "", -1, "/", "", false, true) + return + } + claims.ExpiresAt = expiresAt + claims.UpdatedAt = &jwt.NumericDate{time.Now()} + + token = jwt.NewWithClaims(token.Method, claims) + signedToken, err := token.SignedString(Cfg.GetJWTKey()) + if err == nil { + c.SetCookie("jwt", signedToken, 60*60*24*MaxTokenAgeInDays, "/", "", CookieSecure, true) + } + logger.Error(signedToken) + } + user, err := daoWrapper.UsersDao.GetUserByID(c, token.Claims.(*JWTClaims).UserID) if err != nil { c.Set("TUMLiveContext", TUMLiveContext{}) diff --git a/tools/session.go b/tools/session.go index 1bd087bbc..712954156 100644 --- a/tools/session.go +++ b/tools/session.go @@ -30,8 +30,10 @@ func createToken(user uint, samlSubjectID *string, rememberMe bool) (string, err t.Claims = &JWTClaims{ RegisteredClaims: &jwt.RegisteredClaims{ + IssuedAt: &jwt.NumericDate{Time: time.Now()}, ExpiresAt: &jwt.NumericDate{Time: time.Now().Add(time.Hour * 24 * MaxTokenAgeInDays)}, // Token expires in one week }, + UpdatedAt: &jwt.NumericDate{Time: time.Now()}, UserID: user, SamlSubjectID: samlSubjectID, RememberMe: rememberMe,