Skip to content

Commit

Permalink
Merge pull request #192 from cerberauth/change-jwt-expiration-time
Browse files Browse the repository at this point in the history
Set the JWT expiration time in the future if the token has expired
  • Loading branch information
emmanuelgautier authored Oct 5, 2024
2 parents add9525 + 1209919 commit b0f0ab3
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 35 deletions.
13 changes: 13 additions & 0 deletions jwt/jwt_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package jwt

import (
"errors"
"time"

"github.com/golang-jwt/jwt/v5"
)
Expand All @@ -24,6 +25,18 @@ func NewJWTWriter(token string) (*JWTWriter, error) {
}

func (j *JWTWriter) SignWithMethodAndKey(method jwt.SigningMethod, key interface{}) (string, error) {
// If the token has expired, we will extend it for 5 minutes so that it can pass the verification
expirationTime, err := j.Token.Claims.GetExpirationTime()
if err == nil && expirationTime != nil && expirationTime.Before(time.Now()) {
claims := j.Token.Claims.(jwt.MapClaims)
newClaims := jwt.MapClaims{}
for k, v := range claims {
newClaims[k] = v
}
newClaims["exp"] = time.Now().Add(5 * time.Minute).Unix()
j.Token.Claims = newClaims
}

newToken := jwt.NewWithClaims(method, j.Token.Claims)

tokenString, err := newToken.SignedString(key)
Expand Down
62 changes: 27 additions & 35 deletions jwt/jwt_writer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,65 +8,57 @@ import (
"github.com/stretchr/testify/assert"
)

func TestJWTWriter_SignWithMethodAndRandomKey_WhenSigningMethodIsHS256(t *testing.T) {
func TestJWTWriter_SignWithMethodAndRandomKey_SigningMethodIsHS256(t *testing.T) {
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
tokenParsed, _, _ := new(libjwt.Parser).ParseUnverified(token, libjwt.MapClaims{})
writer, _ := jwt.NewJWTWriter(token)

token, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodHS256)
newToken, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodHS256)
assert.NoError(t, err)
assert.NotEmpty(t, token)
}

func TestJWTWriter_SignWithMethodAndRandomKey_WhenSigningMethodIsRS256(t *testing.T) {
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
writer, _ := jwt.NewJWTWriter(token)
assert.NotEqual(t, token, newToken)

token, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodRS256)
newTokenParsed, _, err := new(libjwt.Parser).ParseUnverified(newToken, libjwt.MapClaims{})
assert.NoError(t, err)
assert.NotEmpty(t, token)
assert.Equal(t, libjwt.SigningMethodHS256, newTokenParsed.Method)
assert.Equal(t, tokenParsed.Claims, newTokenParsed.Claims)
}

func TestJWTWriter_SignWithMethodAndRandomKey_WhenSigningMethodIsRS384(t *testing.T) {
func TestJWTWriter_SignWithMethodAndRandomKey_SigningMethodIsHS512(t *testing.T) {
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
tokenParsed, _, _ := new(libjwt.Parser).ParseUnverified(token, libjwt.MapClaims{})
writer, _ := jwt.NewJWTWriter(token)

token, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodRS384)
newToken, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodHS512)
assert.NoError(t, err)
assert.NotEmpty(t, token)
}
assert.NotEqual(t, token, newToken)

func TestJWTWriter_SignWithMethodAndRandomKey_WhenSigningMethodIsRS512(t *testing.T) {
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
writer, _ := jwt.NewJWTWriter(token)

token, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodRS512)
newTokenParsed, _, err := new(libjwt.Parser).ParseUnverified(newToken, libjwt.MapClaims{})
assert.NoError(t, err)
assert.NotEmpty(t, token)
assert.Equal(t, libjwt.SigningMethodHS512, newTokenParsed.Method)
assert.Equal(t, tokenParsed.Claims, newTokenParsed.Claims)
}

func TestJWTWriter_SignWithMethodAndRandomKey_WhenSigningMethodIsES256(t *testing.T) {
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
func TestJWTWriter_SignWithMethodAndKey_WhenTokenExpired(t *testing.T) {
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyMzkwMjJ9.4Adcj3UFYzPUVaVF43FmMab6RlaQD8A9V8wFzzht-KQ"
tokenParsed, _, _ := new(libjwt.Parser).ParseUnverified(token, libjwt.MapClaims{})
writer, _ := jwt.NewJWTWriter(token)

token, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodES256)
newToken, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodHS256)
assert.NoError(t, err)
assert.NotEmpty(t, token)
}
assert.NotEqual(t, token, newToken)

func TestJWTWriter_SignWithMethodAndRandomKey_WhenSigningMethodIsES384(t *testing.T) {
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
writer, _ := jwt.NewJWTWriter(token)

token, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodES384)
newTokenParsed, _, err := new(libjwt.Parser).ParseUnverified(newToken, libjwt.MapClaims{})
assert.NoError(t, err)
assert.NotEmpty(t, token)
}
assert.Equal(t, libjwt.SigningMethodHS256, newTokenParsed.Method)

func TestJWTWriter_SignWithMethodAndRandomKey_WhenSigningMethodIsES512(t *testing.T) {
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
writer, _ := jwt.NewJWTWriter(token)
subject, _ := tokenParsed.Claims.GetSubject()
newSubject, _ := newTokenParsed.Claims.GetSubject()
assert.Equal(t, subject, newSubject)

token, err := writer.SignWithMethodAndRandomKey(libjwt.SigningMethodES512)
assert.NoError(t, err)
assert.NotEmpty(t, token)
expirationTime, _ := tokenParsed.Claims.GetExpirationTime()
newExpirationTime, _ := newTokenParsed.Claims.GetExpirationTime()
assert.True(t, expirationTime.Before(newExpirationTime.Time))
}

0 comments on commit b0f0ab3

Please sign in to comment.