Overview
The isSessionTokenValid() function validates session tokens to ensure they haven’t expired and match the expected format. It checks token structure, timestamp validity, optional user ID matching, and expiration times.
Common Use Cases
- Session management and authentication
- Token-based authentication validation
- API request authentication
- Stateless session validation
- Token expiration checking
Function Signature
isSessionTokenValid(token, options)
Parameters
The session token to validate.
Configuration options for token validation.The length of the random part of the token. Must match the length used when generating the token.
options.userID
string | null
default:"null"
The user ID associated with the session. If provided, the validator will verify it matches the token.
The expiration time for the token. Format: <number><unit> where unit is s (seconds), m (minutes), h (hours), or d (days).
Examples: '30m', '1h', '7d', '3600s'
Whether the token includes a timestamp. Must be true to validate expiration.
Whether to return detailed validation information instead of a boolean.
Return Value
When details is false: Returns true if token is valid and not expired, false otherwise.When details is true: Returns an object with the following properties:Whether the token is valid and not expired.
Array of validation error messages, or null if valid.
The token that was validated.
The timestamp extracted from the token (milliseconds since epoch).
The expiration timestamp (milliseconds since epoch).
Time remaining until expiration in milliseconds. Negative if expired.
Examples
Basic Token Validation
Simple Validation
With User ID
Detailed Validation
import { isSessionTokenValid } from 'validauth';
// Assume you have a token generated with default settings
const token = 'abc123...timestamp...'; // Your actual token
// Validate with default settings (1 hour expiration)
const isValid = isSessionTokenValid(token, {
expiresIn: '1h'
});
if (isValid) {
console.log('Token is valid');
} else {
console.log('Token is invalid or expired');
}
import { isSessionTokenValid } from 'validauth';
// Validate token with user ID verification
const isValid = isSessionTokenValid(token, {
length: 32,
userID: 'user123',
expiresIn: '1h',
includeTimestamp: true
});
// Returns true only if token is valid, not expired,
// and contains the correct user ID
import { isSessionTokenValid } from 'validauth';
const result = isSessionTokenValid(token, {
expiresIn: '30m',
details: true
});
console.log(result);
/* Returns:
{
valid: true,
errors: null,
token: 'abc123...',
timestamp: 1678901234567,
expiresAt: 1678903034567,
remainingTime: 1234567 // milliseconds remaining
}
*/
// Calculate minutes remaining
const minutesRemaining = Math.floor(result.remainingTime / 60000);
console.log(`Token expires in ${minutesRemaining} minutes`);
Session Management Example
import { isSessionTokenValid } from 'validauth';
import { generateSessionToken } from 'validauth'; // Assuming this exists
class SessionManager {
constructor() {
this.sessions = new Map();
}
// Create a new session
createSession(userID) {
// Generate token (you'd implement this based on your token generation)
const token = this.generateToken(userID);
this.sessions.set(token, {
userID: userID,
createdAt: Date.now(),
lastActivity: Date.now()
});
return token;
}
// Validate existing session
validateSession(token, userID) {
const result = isSessionTokenValid(token, {
length: 32,
userID: userID,
expiresIn: '1h',
includeTimestamp: true,
details: true
});
if (!result.valid) {
// Clean up expired session
this.sessions.delete(token);
return {
valid: false,
message: this.getErrorMessage(result.errors)
};
}
// Update last activity
const session = this.sessions.get(token);
if (session) {
session.lastActivity = Date.now();
}
return {
valid: true,
remainingTime: result.remainingTime,
expiresAt: result.expiresAt
};
}
// Check if token needs refresh (e.g., less than 10 minutes remaining)
shouldRefreshToken(token, userID) {
const result = isSessionTokenValid(token, {
userID: userID,
expiresIn: '1h',
details: true
});
if (!result.valid) {
return false;
}
// Refresh if less than 10 minutes remaining
const tenMinutes = 10 * 60 * 1000;
return result.remainingTime < tenMinutes;
}
getErrorMessage(errors) {
if (!errors || errors.length === 0) {
return 'Unknown error';
}
const errorMap = {
'Token has expired': 'Your session has expired. Please log in again.',
'UserID mismatch in token': 'Invalid session. Please log in again.',
'Invalid timestamp in token': 'Invalid session token.',
'Token must be a non-empty string': 'No session token provided.'
};
return errorMap[errors[0]] || errors[0];
}
generateToken(userID) {
// Simplified token generation
const randomPart = Math.random().toString(36).substring(2, 34);
const timestamp = Date.now().toString();
return randomPart + timestamp + userID;
}
}
// Usage
const sessionManager = new SessionManager();
// Create session
const token = sessionManager.createSession('user123');
// Validate session
const validation = sessionManager.validateSession(token, 'user123');
if (validation.valid) {
console.log('Session is active');
// Check if token should be refreshed
if (sessionManager.shouldRefreshToken(token, 'user123')) {
console.log('Token should be refreshed');
}
} else {
console.log(validation.message);
}
API Authentication Middleware
import { isSessionTokenValid } from 'validauth';
function authMiddleware(options = {}) {
const defaultOptions = {
tokenHeader: 'Authorization',
tokenPrefix: 'Bearer ',
expiresIn: '1h',
...options
};
return async (req, res, next) => {
try {
// Extract token from header
const authHeader = req.headers[defaultOptions.tokenHeader.toLowerCase()];
if (!authHeader) {
return res.status(401).json({
error: 'No authorization token provided'
});
}
// Remove Bearer prefix if present
const token = authHeader.startsWith(defaultOptions.tokenPrefix)
? authHeader.slice(defaultOptions.tokenPrefix.length)
: authHeader;
// Validate token
const result = isSessionTokenValid(token, {
length: 32,
expiresIn: defaultOptions.expiresIn,
includeTimestamp: true,
details: true
});
if (!result.valid) {
return res.status(401).json({
error: 'Invalid or expired token',
details: result.errors
});
}
// Attach token info to request
req.token = token;
req.tokenInfo = {
timestamp: result.timestamp,
expiresAt: result.expiresAt,
remainingTime: result.remainingTime
};
// Warn if token is expiring soon (less than 5 minutes)
if (result.remainingTime < 5 * 60 * 1000) {
res.setHeader('X-Token-Expiring', 'true');
res.setHeader('X-Token-Remaining', result.remainingTime.toString());
}
next();
} catch (error) {
console.error('Auth middleware error:', error);
res.status(500).json({
error: 'Authentication error'
});
}
};
}
// Usage with Express
// app.use('/api', authMiddleware({ expiresIn: '2h' }));
Token Refresh Strategy
import { isSessionTokenValid } from 'validauth';
class TokenRefreshManager {
constructor(refreshThresholdMs = 10 * 60 * 1000) { // 10 minutes
this.refreshThreshold = refreshThresholdMs;
}
// Check if token needs refresh
needsRefresh(token, expiresIn = '1h') {
const result = isSessionTokenValid(token, {
expiresIn: expiresIn,
details: true
});
if (!result.valid) {
return {
needsRefresh: true,
reason: 'expired',
errors: result.errors
};
}
if (result.remainingTime < this.refreshThreshold) {
return {
needsRefresh: true,
reason: 'expiring-soon',
remainingTime: result.remainingTime
};
}
return {
needsRefresh: false,
remainingTime: result.remainingTime
};
}
// Refresh token if needed
async autoRefresh(token, refreshCallback) {
const check = this.needsRefresh(token);
if (check.needsRefresh) {
console.log(`Refreshing token: ${check.reason}`);
return await refreshCallback();
}
return token;
}
}
// Usage
const refreshManager = new TokenRefreshManager();
// Check if refresh is needed
const check = refreshManager.needsRefresh(currentToken, '1h');
if (check.needsRefresh) {
console.log(`Token needs refresh: ${check.reason}`);
// Request new token from server
}
// Auto-refresh example
const token = await refreshManager.autoRefresh(
currentToken,
async () => {
// Your token refresh logic
const response = await fetch('/api/refresh-token', {
method: 'POST',
headers: { 'Authorization': `Bearer ${currentToken}` }
});
const data = await response.json();
return data.newToken;
}
);
Multi-Tier Session Expiration
import { isSessionTokenValid } from 'validauth';
class TieredSessionManager {
validateWithTiers(token, userID, sessionType = 'standard') {
// Different expiration times for different session types
const sessionTiers = {
'short': '30m', // Quick actions
'standard': '1h', // Normal browsing
'extended': '24h', // Remember me
'api': '7d' // API keys
};
const expiresIn = sessionTiers[sessionType] || sessionTiers.standard;
const result = isSessionTokenValid(token, {
length: 32,
userID: userID,
expiresIn: expiresIn,
includeTimestamp: true,
details: true
});
if (!result.valid) {
return {
valid: false,
message: 'Session expired or invalid',
errors: result.errors
};
}
// Calculate time remaining in a friendly format
const timeRemaining = this.formatTimeRemaining(result.remainingTime);
return {
valid: true,
sessionType: sessionType,
expiresIn: expiresIn,
timeRemaining: timeRemaining,
shouldWarn: result.remainingTime < 5 * 60 * 1000 // Warn if < 5 min
};
}
formatTimeRemaining(ms) {
const hours = Math.floor(ms / (60 * 60 * 1000));
const minutes = Math.floor((ms % (60 * 60 * 1000)) / (60 * 1000));
if (hours > 0) {
return `${hours}h ${minutes}m`;
}
return `${minutes}m`;
}
}
// Usage
const tieredManager = new TieredSessionManager();
const result = tieredManager.validateWithTiers(token, 'user123', 'extended');
if (result.valid) {
console.log(`Session valid for ${result.timeRemaining}`);
if (result.shouldWarn) {
console.warn('Session expiring soon!');
}
}
Validation Rules
Token Structure Requirements
- Token must be a non-empty string
- Must include timestamp when
includeTimestamp is true
- Token format:
[random_part][timestamp][userID] (if userID is included)
- Timestamp must be parseable as an integer
- Current time must be within the expiration window
Valid expiresIn formats:
'30s' - 30 seconds
'10m' - 10 minutes
'1h' - 1 hour
'7d' - 7 days
Error Messages
The validator returns these error messages:
"Token must be a non-empty string" - Token is missing or not a string
"Token must include timestamp to validate expiration" - includeTimestamp is false
"Invalid expiresIn format (use format like '1h', '30m')" - Malformed expiration time
"Invalid time unit in expiresIn" - Unknown time unit
"UserID mismatch in token" - Token’s userID doesn’t match provided userID
"Invalid timestamp in token" - Timestamp cannot be parsed
"Token has expired" - Token’s expiration time has passed
Best Practices
Security Recommendations
- Always validate tokens on the server side
- Use HTTPS to prevent token interception
- Store tokens securely (httpOnly cookies recommended)
- Implement token refresh before expiration
- Clear tokens on logout
- Never expose token validation logic to clients
- Rotate tokens after sensitive operations
Implementation Tips
- Set appropriate expiration times based on security needs
- Use shorter expirations (30m-1h) for web sessions
- Use longer expirations (7d-30d) for API keys
- Implement automatic token refresh for better UX
- Warn users before token expiration
- Log token validation failures for security monitoring
- Consider using sliding window expiration
- Token validation is very fast (string parsing and timestamp comparison)
- Cache validation results if checking the same token multiple times
- Consider using Redis or similar for distributed session validation
- Implement rate limiting on token validation endpoints
Testing
import { isSessionTokenValid } from 'validauth';
// Generate test token with known timestamp
function generateTestToken(ageMs = 0) {
const randomPart = 'a'.repeat(32);
const timestamp = Date.now() - ageMs;
return randomPart + timestamp;
}
// Test expired token
const expiredToken = generateTestToken(2 * 60 * 60 * 1000); // 2 hours old
const result = isSessionTokenValid(expiredToken, { expiresIn: '1h' });
console.log(result); // false
// Test valid token
const validToken = generateTestToken(30 * 60 * 1000); // 30 minutes old
const result2 = isSessionTokenValid(validToken, { expiresIn: '1h' });
console.log(result2); // true