Hash crypto & JWT
Renew a JWT: Handle Expiration, Inactivity, and Sign-In State
Plan JWT renewal around the issuer’s lifetime and session policy, distinguish expiry display from trust, and handle sleeping clients and failed renewal.
Renewal creates a new credential under issuer policy
Renewing a JWT means obtaining a new token through the issuer's supported process. It does not mutate the old token into a longer-lived credential. The issuer may permit refresh, require another sign-in or refuse renewal because the session was revoked or no longer meets its policy.
Start with the token response and provider documentation. An access token's lifetime is different from the maximum session lifetime or a refresh token's expiration. Successfully renewing once does not imply that the session can continue forever, and an application's interface should be able to represent the need for another sign-in.
Use expiration information for display without treating it as trust
function secondsUntilExpiry(claims, nowSeconds) {
if (typeof claims.exp !== "number" || !Number.isFinite(claims.exp)) {
return null;
}
if (!Number.isFinite(nowSeconds)) {
throw new Error("Use a finite clock value in seconds.");
}
return Math.max(0, claims.exp - nowSeconds);
}
console.assert(secondsUntilExpiry({exp: 2000000300}, 2000000000) === 300);
console.assert(secondsUntilExpiry({exp: 2000000300}, 2000000300) === 0);
This helper calculates a display value from supplied claims and a supplied clock. It does not verify a token, authorize a request or prove that the server will accept the credential. The synthetic values make the arithmetic repeatable without depending on the reader's current date.
The JWT expiration definition uses a NumericDate in seconds. Confusing it with JavaScript milliseconds can make a token appear expired immediately or valid for an implausibly long time. Keep the time unit explicit at the point where values enter the application.
Account for backgrounding and suspended devices
A browser timer is a convenience, not a guarantee that code runs at the exact intended instant. Background tabs, sleeping laptops and disconnected mobile devices can delay a planned renewal. Reassess the session when the application becomes active and before an operation requiring current authorization.
Use a modest, deliberate margin if the provider supports renewing before expiry. Do not keep subtracting an arbitrary margin on every conversion or lengthen the server's acceptance policy to accommodate a poorly synchronized client. The resource server remains responsible for validating the presented token.
A client clock can be wrong. Where possible, base the renewal schedule on the server's documented lifetime information and the client's receipt of the response, while still handling server rejection. A countdown in the interface should not overrule an authoritative authentication failure.
Handle refresh failure as a state transition
Represent renewal-in-progress, renewed access and renewal failure explicitly. If a refresh credential is revoked or expires, stop the retry loop and guide the user back through the required sign-in flow. Do not keep showing a permanent loading indicator while repeatedly sending the same rejected credential.
Coordinate simultaneous renewal requests so that multiple API calls do not all attempt to rotate the same refresh credential. Keep replacement credentials together with the access-token update under the storage design. The OAuth security guidance discusses replay protection and the implications of refresh-token rotation.
Keep business operations separate from session maintenance
After obtaining a new access token, decide whether the original request may be retried. A read and a write can have different replay consequences. A connection interruption may leave a write's outcome uncertain, so a general-purpose renewal helper should not blindly repeat every failed operation.
Likewise, an authorization failure caused by missing scope is not necessarily fixed by a newer token. Compare the requested action with the session's actual permissions. If the user needs a new authorization grant, repeatedly refreshing the old grant cannot create permissions that were never granted.
Test boundaries and the return from inactivity
Test the display helper before expiry, exactly at expiry, after expiry and with an absent or wrongly typed exp value. Then test the real client flow after a long pause, during network loss and after the refresh credential is revoked. A working countdown is only a small part of that lifecycle.
The JWT Decoder can help read synthetic timing claims and spot a seconds-versus-milliseconds mistake. It does not renew a real session or check the issuer's current account state. Keep that distinction visible in diagnostics so that an inspection result is never mistaken for renewed authorization.


