Skip to main content

Session Management in the Integration Environment

This guide explains how to manage sessions when working with the FinHub API in the Integration environment, which implements production-equivalent session handling.

Session Tokens Overview

When a user logs in through the authentication endpoints, the system creates a session and returns several tokens:
{
  "expires_in": 3600,
  "token_type": "Bearer",
  "scope": "01f0418c-36da-17a0-830a-aca6bf25e007",
  "customerId": "12345678-abcd-1234-efgh-1234567890ab",
  "tenantId": "1234567",
  "userSessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Key Session Components

ComponentDescriptionUsage
userSessionTokenJWT token for user session validationUsed for session validation and contains user identity claims
refreshTokenToken used to obtain a new session token without re-authenticationUsed when the session token expires
customerIdUnique identifier for the customerReference in customer-related operations
tenantIdIdentifier for the tenantUsed for multi-tenant operations

Required Session Headers

Every API request in the FinHub Integration environment must include these headers:
HeaderDescriptionRequiredExample
AuthorizationBearer token for authenticationYesBearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
X-Activity-IDUUID that identifies a specific user activity or flowYes550e8400-e29b-41d4-a716-446655440000
X-Tenant-IDTenant identifier for multi-tenant operationsYes1234567
X-Session-IDOptional session identifier for session trackingNosession-12345678
X-Correlation-IDOptional identifier for request correlationNocorr-12345678

Activity ID Generation

The Activity ID should be a UUID (v4) generated for each distinct user activity or flow. For example:
  • Tab
  • Tab
  • Tab
// Generate a random UUID v4
const activityId = crypto.randomUUID();

Session Lifecycle Management

Session Creation

A session is created when a user successfully authenticates through the login endpoint. The session includes:
  1. A user session token (JWT)
  2. A refresh token for token renewal
  3. An internally managed access token (not exposed to clients)
  4. User identity information

Token Refresh

In the Integration environment, you can refresh an expired token without requiring the user to re-enter credentials:
  • Tab
  • Tab
  • Tab
async function refreshToken() {
  const refreshToken = localStorage.getItem('refreshToken');
  const tenantId = localStorage.getItem('tenantId');
  
  const response = await fetch('https://integration.finhub.cloud/api/v2.1/auth/token/refresh', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Tenant-ID': tenantId
    },
    body: JSON.stringify({
      refreshToken: refreshToken,
      customerId: 'OQ1GG9iFxVcgzforkJR8CImHiuwa',
      customerSecret: 'lPGwgaAENdwLxtfuqQu5R606jswa'
    })
  });
  
  const refreshData = await response.json();
  
  // Update stored tokens
  localStorage.setItem('userSessionToken', refreshData.userSessionToken);
  localStorage.setItem('refreshToken', refreshData.refreshToken);
  localStorage.setItem('tokenExpiry', Date.now() + (refreshData.expires_in * 1000));
  
  return refreshData.userSessionToken;
}

Session Expiration Handling

To handle session expiration gracefully:
  1. Monitor token expiration: Check the token expiration before making API requests
  2. Implement automatic refresh: Refresh the token when it’s close to expiration
  3. Handle refresh failures: If refresh fails, redirect to the login page
  • Tab
// Example of token expiration handling in an API request wrapper
async function apiRequest(url, method = 'GET', data = null) {
  // Check if token is expired or about to expire (within 5 minutes)
  const tokenExpiry = localStorage.getItem('tokenExpiry');
  const isTokenExpired = Date.now() > tokenExpiry - (5 * 60 * 1000);
  
  // If token is expired or about to expire, refresh it
  if (isTokenExpired) {
    try {
      await refreshToken();
    } catch (error) {
      // If refresh fails, redirect to login
      window.location.href = '/login';
      return;
    }
  }
  
  // Get the current token
  const userSessionToken = localStorage.getItem('userSessionToken');
  const tenantId = localStorage.getItem('tenantId');
  const activityId = localStorage.getItem('activityId');
  
  // Make the API request
  const response = await fetch(url, {
    method,
    headers: {
      'Authorization': `Bearer ${userSessionToken}`,
      'Content-Type': 'application/json',
      'X-Tenant-ID': tenantId,
      'X-Activity-ID': activityId
    },
    body: data ? JSON.stringify(data) : undefined
  });
  
  // Handle 401 errors (token expired or invalid)
  if (response.status === 401) {
    try {
      await refreshToken();
      // Retry the request with the new token
      return apiRequest(url, method, data);
    } catch (error) {
      // If refresh fails, redirect to login
      window.location.href = '/login';
      return;
    }
  }
  
  return response.json();
}

Session Termination

To explicitly terminate a session, call the logout endpoint:
POST /api/v2.1/auth/logout HTTP/1.1
Host: integration.finhub.cloud
Content-Type: application/json
X-Tenant-ID: 1234567
X-Activity-ID: 550e8400-e29b-41d4-a716-446655440000
X-Session-Active: true
X-User-Session-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
  • Tab
async function logout() {
  const userSessionToken = localStorage.getItem('userSessionToken');
  const tenantId = localStorage.getItem('tenantId');
  const activityId = localStorage.getItem('activityId');
  
  try {
    await fetch('https://integration.finhub.cloud/api/v2.1/auth/logout', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${userSessionToken}`,
        'Content-Type': 'application/json',
        'X-Tenant-ID': tenantId,
        'X-Activity-ID': activityId
      }
    });
  } finally {
    // Clear all session data regardless of logout API success
    localStorage.removeItem('userSessionToken');
    localStorage.removeItem('refreshToken');
    localStorage.removeItem('tokenExpiry');
    localStorage.removeItem('tenantId');
    localStorage.removeItem('activityId');
    
    // Redirect to login page
    window.location.href = '/login';
  }
}

Session Security Best Practices

Token Storage

Store tokens securely based on your platform:
PlatformRecommended StorageNot Recommended
Web BrowserHttpOnly cookies, Session StorageLocal Storage, JavaScript variables
Mobile AppsSecure Keychain (iOS), Keystore (Android)SharedPreferences, UserDefaults
Server-sideEncrypted database, RedisEnvironment variables, config files

Token Transmission

  • Always use HTTPS for all API requests
  • Use Bearer authentication scheme in the Authorization header
  • Never include tokens in URLs or query parameters
  • Implement CSRF protection for web applications

Session Monitoring

  • Implement session activity logging
  • Monitor for suspicious session activities
  • Set up alerts for unusual session patterns
  • Implement rate limiting for authentication endpoints

Differences from Playground

FeaturePlaygroundIntegration
Token ExpirationLonger (10000s)Standard (3600s)
Refresh TokenNot providedProvided
Session HeadersBasicComprehensive
Security RequirementsLenientStrict

Moving to Production

When you’re ready to move from the Integration to the Production environment, you’ll need to implement additional session security measures. See the Production Session Management guide for details.

Playground Reference

For simplified testing and experimentation, you can always return to the Playground Session Management guide.

Need Integration Support?

If you encounter any issues with session management in the Integration environment, please contact our integration support team at integration-support@finhub.cloud.
I