Keywords: JWT Tokens | Non-Expiring | Security Risks
Abstract: This technical paper provides an in-depth analysis of non-expiring JWT token implementation using the jsonwebtoken library. It examines the optional nature of the exp claim in JWT specification, demonstrates complete code examples for creating perpetual tokens, and discusses critical security implications. The content covers token structure, signature mechanisms, payload construction, and best practices for token management in production environments.
Fundamental Structure and Expiration Mechanism of JWT
JSON Web Token (JWT), as an open standard (RFC 7519), is widely adopted in modern web applications for authentication and information exchange. JWT consists of three components: Header, Payload, and Signature. The Header contains metadata about token type and signing algorithm, the Payload carries claim information, and the Signature ensures token integrity.
Implementation Principles of Non-Expiring JWT Tokens
In the JWT specification, the exp (expiration time) claim is optional. When a token omits this claim, it is considered valid indefinitely. Using the jsonwebtoken library, this effect is achieved by simply omitting the expiresIn option.
const jwt = require('jsonwebtoken');
const payload = { email_id: '123@gmail.com' };
const secret = 'Stack';
const token = jwt.sign(payload, secret, {});
console.log('Generated non-expiring token:', token);
In the above code, an empty object is passed as the third parameter, explicitly indicating no expiration settings. Tokens generated through this method remain valid indefinitely until explicitly revoked.
Alternative Approaches for Expiration Settings
While non-expiring tokens are possible, practical implementations typically recommend setting reasonable expiration periods. The jsonwebtoken library supports various time formats:
// Multiple expiration time setting methods
const token1 = jwt.sign(payload, secret, { expiresIn: '365d' }); // 365 days
const token2 = jwt.sign(payload, secret, { expiresIn: '8760h' }); // 1 year (8760 hours)
const token3 = jwt.sign(payload, secret, { expiresIn: 31536000 }); // 1 year (in seconds)
Time formats support numeric values (seconds) or string descriptions such as "2 days", "10h", "7d". Note that pure numbers default to seconds, while strings must explicitly specify time units.
Technical Details of Direct exp Claim Setting
Beyond using the expiresIn option, developers can directly set the exp claim in the payload:
const futureTimestamp = Math.floor(Date.now() / 1000) + (365 * 24 * 60 * 60);
const token = jwt.sign({
email_id: '123@gmail.com',
exp: futureTimestamp
}, secret);
This approach offers more precise time control but requires attention to timestamp format (Unix timestamp in seconds). Importantly, exp-related claims cannot be set simultaneously in both payload and options.
Security Risks and Best Practices
Non-expiring JWT tokens present significant security risks. If compromised, attackers gain permanent access to protected resources. Recommended security practices include:
- Setting reasonable expiration periods (e.g., 24 hours)
- Implementing token refresh mechanisms
- Using HTTPS for token transmission
- Regularly rotating signing keys
- Maintaining token blacklists on the server side
Technical Implementation Considerations
During development, note that the jsonwebtoken library does not set default values for expiresIn—it must be explicitly specified or completely omitted. During token verification, the library automatically checks the exp claim; if present and expired, verification fails. For non-expiring tokens, verification always succeeds (unless the signature is invalid).
In practical applications, carefully balance business requirements and security needs when selecting token expiration strategies. Non-expiring tokens should only be used in specific scenarios, such as device binding or long-term trust relationships, and must be complemented with additional security measures.