A lightweight, dependency-free JavaScript module for issuing, verifying, and revoking JWT-style authentication tokens. Designed for educational purposes and small-scale applications requiring basic token-based authentication with key rotation, expiration handling, and revocation capabilities.
- Token Creation: Generate signed tokens with custom payloads and expiration times
- Token Verification: Validate token signatures and check revocation status
- Token Revocation: Maintain a revocation list for invalidated tokens
- Key Rotation: Automatic key rotation with configurable intervals
- Base64URL Encoding: RFC 4648 compliant encoding/decoding
- Zero Dependencies: No external libraries required
git clone https://github.com/your-username/token-auth.git
cd token-auth
import { issueToken, verifyToken, decodeToken, revokeToken } from './src/TokenService.js'
import { issueToken, verifyToken, decodeToken, revokeToken } from './src/TokenService.js'
// Create a token
const payload = {
userId: 123,
role: 'admin',
permissions: ['read', 'write']
}
const token = issueToken(payload, 3600) // 1 hour expiration
console.log('Token:', token)
// Verify a token
const verification = verifyToken(token)
if (verification.valid) {
console.log('Token is valid:', verification.payload)
} else {
console.log('Token invalid:', verification.error)
}
// Decode token payload (without verification)
const decodedPayload = decodeToken(token)
console.log('Decoded payload:', decodedPayload)
// Revoke a token
const success = revokeToken(decodedPayload.jti, 'User logged out')
console.log('Revocation successful:', success)
function authenticateRequest(token) {
const result = verifyToken(token)
if (!result.valid) {
throw new Error(`Authentication failed: ${result.error}`)
}
// Check if token is expired
if (result.payload.exp < Math.floor(Date.now() / 1000)) {
throw new Error('Token has expired')
}
return result.payload
}
// Usage
try {
const userInfo = authenticateRequest(userToken)
console.log(`Authenticated user: ${userInfo.userId}`)
} catch (error) {
console.error('Authentication error:', error.message)
}
class SessionManager {
constructor() {
this.activeSessions = new Map()
}
login(userId, userData) {
const payload = { userId, ...userData }
const token = issueToken(payload, 24 * 60 * 60) // 24 hours
const decoded = decodeToken(token)
this.activeSessions.set(userId, decoded.jti)
return token
}
logout(userId) {
const jti = this.activeSessions.get(userId)
if (jti) {
revokeToken(jti, 'User logout')
this.activeSessions.delete(userId)
return true
}
return false
}
validateSession(token) {
const result = verifyToken(token)
if (result.valid) {
return result.payload
}
return null
}
}
Creates a new JWT token with the specified payload and expiration time.
Parameters:
payload
(Object): Data to include in the tokenttlSeconds
(Number): Time-to-live in seconds
Returns: String - The signed JWT token
Example:
const token = issueToken({ userId: 123, role: 'user' }, 3600)
Verifies a token's signature and checks if it has been revoked.
Parameters:
token
(String): The JWT token to verify
Returns: Object with properties:
valid
(Boolean): Whether the token is validpayload
(Object): Token payload if validerror
(String): Error message if invalid
Example:
const result = verifyToken(token)
if (result.valid) {
console.log('User ID:', result.payload.userId)
}
Decodes a token's payload without verification.
Parameters:
token
(String): The JWT token to decode
Returns: Object - The decoded payload
Example:
const payload = decodeToken(token)
console.log('Token expires at:', new Date(payload.exp * 1000))
Adds a token to the revocation list.
Parameters:
jti
(String): The token's unique identifierreason
(String): Reason for revocation
Returns: Boolean - Always returns true
Example:
const payload = decodeToken(token)
revokeToken(payload.jti, 'Security breach')
Manually triggers key rotation.
Example:
rotateKey() // Forces generation of new signing key
Tokens follow JWT format with three base64url-encoded sections:
header.payload.signature
{
"alg": "RS256",
"typ": "JWT",
"kid": "1609459200000"
}
{
"userId": 123,
"role": "admin",
"iat": 1609459200,
"exp": 1609462800,
"jti": "16094592000001a2b3c4"
}
jsonwebtoken
or jose
.
- Uses basic hash-based signatures instead of RSA/ECDSA
- No key persistence across application restarts
- In-memory revocation store (not persistent)
- No token refresh mechanism
- No rate limiting or brute force protection
- Use HTTPS in production environments
- Implement short token expiration times
- Store tokens securely (httpOnly cookies recommended)
- Implement proper session management
- Use environment variables for sensitive configuration
- Implement token refresh workflows for long-lived sessions
node test-app/app-test.js
node test-app/functions-test.js
This is an educational project. Feel free to:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
MIT License - see LICENSE file for details.
- v1.0.0 - Initial release with basic token operations
- Features: Token creation, verification, revocation, key rotation