Skip to content

Commit c611749

Browse files
authored
Merge pull request #27 from masonsxu/fix/orig-iat-reset-on-refresh
fix: preserve orig_iat on token refresh to maintain MaxRefresh window
1 parent f1fcf31 commit c611749

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

auth_jwt.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,13 @@ func (mw *HertzJWTMiddleware) RefreshToken(ctx context.Context, c *app.RequestCo
633633

634634
expire := mw.TimeFunc().Add(mw.TimeoutFunc(copyClaims))
635635
newClaims["exp"] = expire.Unix()
636-
newClaims["orig_iat"] = mw.TimeFunc().Unix()
636+
// Preserve the original orig_iat to maintain MaxRefresh window
637+
if origIat, exists := claims["orig_iat"]; exists {
638+
newClaims["orig_iat"] = origIat
639+
} else {
640+
// If orig_iat doesn't exist (backward compatibility), set it to current time
641+
newClaims["orig_iat"] = mw.TimeFunc().Unix()
642+
}
637643
tokenString, err := mw.signedString(newToken)
638644
if err != nil {
639645
return "", time.Now(), err

auth_jwt_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,50 @@ func TestExpiredTokenWithinMaxRefreshOnRefreshHandler(t *testing.T) {
548548
assert.DeepEqual(t, http.StatusOK, w.Code)
549549
}
550550

551+
func TestOrigIatPreservedOnRefresh(t *testing.T) {
552+
// Test that orig_iat is preserved when refreshing a token
553+
authMiddleware, _ := New(&HertzJWTMiddleware{
554+
Realm: "test zone",
555+
Key: key,
556+
Timeout: time.Hour,
557+
MaxRefresh: 2 * time.Hour,
558+
Authenticator: defaultAuthenticator,
559+
})
560+
561+
handler := hertzHandler(authMiddleware)
562+
563+
// Create initial token with orig_iat set to 1 hour ago
564+
originalOrigIat := time.Now().Add(-time.Hour).Unix()
565+
token := jwt.New(jwt.GetSigningMethod("HS256"))
566+
claims := token.Claims.(jwt.MapClaims)
567+
claims["identity"] = "admin"
568+
claims["exp"] = time.Now().Add(-time.Minute).Unix() // Expired 1 minute ago
569+
claims["orig_iat"] = originalOrigIat
570+
tokenString, _ := token.SignedString(key)
571+
572+
// Refresh the token
573+
w := ut.PerformRequest(handler, http.MethodGet, "/auth/refresh_token", nil, ut.Header{Key: "Authorization", Value: "Bearer " + tokenString})
574+
assert.DeepEqual(t, http.StatusOK, w.Code)
575+
576+
// Parse the response to get the new token
577+
var response map[string]interface{}
578+
err := json.Unmarshal(w.Body.Bytes(), &response)
579+
assert.Nil(t, err)
580+
newTokenString, ok := response["token"].(string)
581+
assert.True(t, ok)
582+
583+
// Parse the new token and verify orig_iat is preserved
584+
newToken, err := jwt.Parse(newTokenString, func(token *jwt.Token) (interface{}, error) {
585+
return key, nil
586+
})
587+
assert.Nil(t, err)
588+
newClaims := newToken.Claims.(jwt.MapClaims)
589+
newOrigIat, ok := newClaims["orig_iat"].(float64)
590+
assert.True(t, ok)
591+
// orig_iat should be preserved (within 1 second tolerance)
592+
assert.DeepEqual(t, originalOrigIat, int64(newOrigIat))
593+
}
594+
551595
func TestExpiredTokenOnRefreshHandler(t *testing.T) {
552596
// the middleware to test
553597
authMiddleware, _ := New(&HertzJWTMiddleware{

0 commit comments

Comments
 (0)