Skip to content
Returning.AIDocs

Legacy approach. For new integrations, use the Widget SDK with Access Key Embed.

Auth - Token

Token authentication for iframe-embedded widgets using a backend proxy and the postMessage API. The user never sees a login screen - your page handles the token exchange behind the scenes.

Authentication Flow

The token authentication flow has four parts:

  1. Your backend endpoint proxies the Returning.AI signin API (keeps the API key secret).
  2. Your frontend script calls the backend endpoint on page load and stores the token.
  3. The widget iframe requests the token via postMessage when it needs to authenticate.
  4. Your page responds with the stored token via postMessage.

Step 1 - Create a backend proxy endpoint

Create a server-side endpoint that calls the Returning.AI signin API with your secret API key and the authenticated user's email. This endpoint should be protected by your existing authentication middleware.

server.js
app.post('/api/widget-auth', async (req, res) => {
  const userEmail = req.user.email;

  try {
    const response = await fetch(
      'https://prod-widgets.returning.ai/widget/{community_id}/signin',
      {
        method: 'POST',
        headers: {
          'returningai-api-key': process.env.WIDGET_API_KEY,
          'email': userEmail,
          'Content-Type': 'application/json'
        }
      }
    );
    const data = await response.json();
    res.json({ token: data.token });
  } catch (error) {
    res.status(500).json({ error: 'Authentication failed' });
  }
})

Step 2 - Add the frontend authentication script

This script runs on page load. It calls your backend endpoint to obtain a token, stores it in localStorage, and listens for postMessage token requests from the widget iframe.

widget-auth.js
async function authenticateWidget() {
  try {
    const response = await fetch('/api/widget-auth', {
      method: 'POST',
      credentials: 'include'
    });
    const data = await response.json();

    if (data.token) {
      localStorage.setItem('returning-ai-widget-token', data.token);
      console.log('Widget authenticated successfully');
    }
  } catch (error) {
    console.error('Widget authentication failed:', error);
  }
}

window.addEventListener('message', (event) => {
  if (event.origin === 'https://prod-widgets.returning.ai') {
    const { type } = event.data;
    if (type === 'RETURNINGAI_WIDGET_REQUEST_TOKEN') {
      const token = localStorage.getItem('returning-ai-widget-token');
      event.source.postMessage(
        { type: 'RETURNINGAI_WIDGET_TOKEN', value: { token, widgetId: 'YOUR_WIDGET_ID' } },
        event.origin
      );
    }
  }
});

document.addEventListener('DOMContentLoaded', authenticateWidget);

Step 3 - Listen for postMessage token requests

The widget iframe sends a RETURNINGAI_WIDGET_REQUEST_TOKEN message when it needs to authenticate or when the current token expires. The frontend script above already handles this - it validates the origin, retrieves the stored token, and responds with a RETURNINGAI_WIDGET_TOKEN message.

postMessage protocol
// The postMessage exchange looks like this:

// 1. Widget iframe → Your page:
{ type: 'RETURNINGAI_WIDGET_REQUEST_TOKEN' }

// 2. Your page → Widget iframe:
{
  type: 'RETURNINGAI_WIDGET_TOKEN',
  value: {
    token: 'eyJhbGciOiJIUzI1NiIs...',
    widgetId: 'YOUR_WIDGET_ID'
  }
}

Origin validation

Always check that event.origin matches https://prod-widgets.returning.ai before responding to postMessage events. This prevents other iframes or windows from intercepting the token.

Step 4 - Token storage

The token is stored in localStorage under the key returning-ai-widget-token. This allows the token to persist across page navigations within the same session.

BehaviorHow it works
Initial loadFrontend script calls your backend, stores the token in localStorage.
Widget requestWidget iframe sends postMessage, your script responds with the stored token.
Token expiryWidget sends another RETURNINGAI_WIDGET_REQUEST_TOKEN message. Your script should re-fetch from the backend and update localStorage.
User logoutClear the token from localStorage when the user logs out of your platform.
// Clear token on user logout
function onUserLogout() {
  localStorage.removeItem('returning-ai-widget-token');
  // Optionally reload the iframe to reset widget state
  document.getElementById('returningAiWidgetIframe')?.contentWindow?.location.reload();
}

Security Considerations