Skip to content

User Identification

SSO This page explains how FanFest identifies users, what data is synced, and the privacy considerations around user tracking.

How Users Are Identified

When SSO is configured, FanFest recognizes users through a two-step process:

  1. Your site signals a login — You call FanFestSDK.login() when a user authenticates on your site.
  2. The SDK performs silent authentication — The SDK coordinates with your identity provider through a hidden iframe to establish the user's identity within FanFest.

Once authenticated, FanFest knows the user by three attributes:

AttributeSourcePurpose
User IDYour identity provider (sub claim)Primary identifier — links all engagement data
EmailOIDC email scopeReward notifications and account matching
UsernameOIDC profile scopeDisplay name in leaderboards and community features

The Silent Auth Iframe Flow

The silent authentication flow uses a hidden iframe to complete the OIDC handshake without any visible UI. Here is what happens step by step:

1. Login Signal

When you call FanFestSDK.login(), the SDK checks if the user is already authenticated. If they are, the call is a no-op. Otherwise, the SDK begins the silent auth flow.

javascript
// Your site calls this when the user logs in
FanFestSDK.login();

2. Initiation

The SDK sends a POST /auth/silent-initiate request to the FanFest API with a redirect URI pointing to the FanFest app's auth callback page. The API returns an authorization code and state parameter.

3. Hidden Iframe

The SDK creates a 1x1 pixel, invisible iframe and sets its src to the authorization URL. This iframe loads silently in the background — the user sees nothing.

The iframe navigates through your identity provider's silent authentication endpoint (which checks the user's existing session cookies) and completes the OIDC authorization code flow.

4. PostMessage Communication

When the OIDC flow completes in the iframe, the FanFest app sends the result back to the SDK via the browser's postMessage API. The message contains:

  • The authorization code
  • The state parameter (for CSRF protection)
  • The redirect_uri used in the flow

The SDK validates that the message origin matches the configured appOrigin before processing it.

5. Validation

The SDK sends the code, state, and redirect URI to POST /auth/silent-validation on the FanFest API. The API validates the authorization code with your identity provider and returns the authenticated user data.

6. State Storage

On successful validation, the SDK stores the authentication state in localStorage under the key fanfest-auth-token. This includes:

  • Auth token — Session state for API requests
  • User data — ID, email, and username (nullable)
  • Auth channel type — How the user authenticated (oauth or otp)
  • Validated identifiers — Confirmed user identifiers from the provider

The stored state persists across page reloads, so users remain identified until they explicitly log out.

7. Logout

When the user logs out of your site, call FanFestSDK.logout(). This removes the stored auth state from localStorage, and the user reverts to anonymous mode.

javascript
// Your site calls this when the user logs out
FanFestSDK.logout();

What Data Is Synced

FanFest syncs a minimal set of user data — only what is needed for identification and engagement attribution:

DataStored WhereRetention
Auth token (session state)Browser localStorageUntil logout or token expiry
User ID, email, usernameBrowser localStorage + FanFest backendSession-scoped locally; backend per data policy
Auth channel typeBrowser localStorageUntil logout
Engagement actions and pointsFanFest backendPer data retention policy

FanFest does not sync:

  • Passwords or credentials (handled entirely by your identity provider)
  • Payment information
  • Identity provider tokens (the OIDC flow is completed server-side)
  • Browsing history or cookies from your site

The hostLoginFn Callback

When an unauthenticated user interacts with a FanFest feature that requires identification (such as claiming reward points), the SDK can prompt them to log in through your site.

Configure this by providing a hostLoginFn callback during initialization:

javascript
FanFestSDK.init({
  clientId: 'YOUR_WEB_APP_ID',
  hostLoginFn: () => {
    // Trigger your site's login flow
    // Example: redirect to login page, open a modal, etc.
    window.location.href = '/login';
  },
});

The SDK calls hostLoginFn when it needs the user to authenticate. After the user logs in on your site, call FanFestSDK.login() to complete the silent auth flow.

The hostRewardsFn Callback

Similarly, the hostRewardsFn callback lets FanFest deep-link users to a rewards or loyalty page on your site:

javascript
FanFestSDK.init({
  clientId: 'YOUR_WEB_APP_ID',
  hostRewardsFn: () => {
    // Navigate the user to your rewards page
    router.push('/rewards');
  },
});

This callback is triggered from within the FanFest embed when users want to view or redeem their accumulated rewards.

Privacy Considerations

Minimal Data Collection

FanFest follows a minimal data collection principle for SSO:

  • Only the OIDC openid, profile, and email scopes are requested
  • No additional user profile data is pulled from your identity provider
  • The SDK stores only what is returned by the FanFest API validation endpoint

Client-Side Storage

Authentication state is stored in localStorage, which means:

  • It is scoped to the origin of your website
  • It is not shared across domains
  • It is cleared when the user calls FanFestSDK.logout() or clears browser storage
  • It does not use cookies — no cross-site tracking

Secure Communication

  • All API communication uses HTTPS
  • The hidden iframe's postMessage is validated against the configured appOrigin
  • PKCE (Proof Key for Code Exchange) is used for the OIDC flow to prevent authorization code interception
  • The authorization code exchange happens server-side (FanFest API to identity provider)

User Control

Users can:

  • Use your site without SSO (anonymous FanFest experience)
  • Log out at any time via FanFestSDK.logout()
  • Clear localStorage to remove all stored state

Released under the MIT License.