Step 5: Token Management

Proper token management is crucial for maintaining secure and seamless user sessions. This step covers secure token storage, automatic refresh, and best practices for token lifecycle management.

Need context? Check the Integration Flow Overview to see how this step fits into the complete process.

What You'll Learn

In this step, you will:

  • Store tokens securely in different environments

  • Implement automatic token refresh

  • Handle token expiration gracefully

  • Manage token lifecycle and cleanup

  • Use tokens for API calls

  • Implement proper security measures

Secure Token Storage

For server-side applications, store tokens in encrypted form:

const crypto = require('crypto');

class TokenManager {
  constructor(encryptionKey) {
    this.encryptionKey = encryptionKey;
    this.algorithm = 'aes-256-gcm';
  }
  
  encrypt(text) {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipher(this.algorithm, this.encryptionKey, iv);
    
    let encrypted = cipher.update(text, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    
    const authTag = cipher.getAuthTag();
    
    return {
      encrypted,
      iv: iv.toString('hex'),
      authTag: authTag.toString('hex')
    };
  }
  
  decrypt(encryptedData) {
    const decipher = crypto.createDecipher(
      this.algorithm, 
      this.encryptionKey, 
      Buffer.from(encryptedData.iv, 'hex')
    );
    
    decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));
    
    let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    
    return decrypted;
  }
  
  async storeTokens(userId, tokens) {
    const tokenData = {
      accessToken: tokens.access_token,
      refreshToken: tokens.refresh_token,
      idToken: tokens.id_token,
      expiresAt: new Date(Date.now() + tokens.expires_in * 1000),
      tokenType: tokens.token_type || 'Bearer',
      scope: tokens.scope
    };
    
    // Encrypt sensitive tokens
    const encryptedData = {
      accessToken: this.encrypt(tokenData.accessToken),
      refreshToken: this.encrypt(tokenData.refreshToken),
      idToken: this.encrypt(tokenData.idToken),
      expiresAt: tokenData.expiresAt,
      tokenType: tokenData.tokenType,
      scope: tokenData.scope
    };
    
    // Store in database
    await database.saveUserTokens(userId, encryptedData);
  }
  
  async getTokens(userId) {
    const encryptedData = await database.getUserTokens(userId);
    if (!encryptedData) return null;
    
    return {
      accessToken: this.decrypt(encryptedData.accessToken),
      refreshToken: this.decrypt(encryptedData.refreshToken),
      idToken: this.decrypt(encryptedData.idToken),
      expiresAt: encryptedData.expiresAt,
      tokenType: encryptedData.tokenType,
      scope: encryptedData.scope
    };
  }
}

// Usage
const tokenManager = new TokenManager(process.env.TOKEN_ENCRYPTION_KEY);

Client-Side Storage (SPAs)

For Single Page Applications, use secure browser storage:

Automatic Token Refresh

Server-Side Token Refresh

Client-Side Token Refresh

🌐 Using Tokens for API Calls

HTTP Client with Automatic Token Refresh

Axios Interceptor Example

Token Lifecycle Management

Token Cleanup and Rotation

Session Management Integration

Monitoring and Metrics

Token Usage Metrics

Token Management Checklist

Ensure your token management:


Progress: Step 5 of 5 complete ✅

Congratulations!

You've successfully completed the Oten IDP integration! Here's what you've accomplished:

Prerequisites - Set up your environment and registered with Oten ✅ JAR Implementation - Understood and implemented JWT-Secured Authorization Request ✅ Library Selection - Chose the right OAuth library for your stack ✅ Client Configuration - Set up your OAuth client with proper endpoints ✅ Authorization Flow - Implemented JAR-based authorization with PKCE ✅ Callback Handling - Processed OAuth callbacks and exchanged codes for tokens ✅ Token Management - Implemented secure token storage and refresh

🚀 What's Next?

Production Readiness

Advanced Features

Support

Happy coding!

Last updated