Authentication

Learn how to implement React Native authentication.

OpenWeb's Single Sign-On (SSO) enables your registered users to participate in members-only conversations without an extra registration. To provide this user experience, your backend user management system must securely inform OpenWeb that a user is actively logged into your site.

SSO Authentication

SSO Handshake Overview

  1. Initiate an OpenWeb SSO session using OpenWeb.manager.authentication.startSSO(). The OpenWeb SDK generates an SSO session ID (codeA).
  2. Send the SSO session ID to your backend user management system.
  3. Validate that a user is logged into your system. You must ensure that the current user logged into your app will also be the current user in the OpenWeb user session.
  4. From your backend user management system, make a GET /sso/v1/register-user call to OpenWeb's backend. The API call must include the following information:
    • Your secret access token (access_token)
    • Session ID generated after initiating the SSO session (code_a)
    • Required user details from your backend user management system (primary_key, user_name).
    • OpenWeb's backend logs in the user and returns a success response (codeB).
  5. Pass codeB to the OpenWeb SDK using OpenWeb.manager.authentication.completeSSO(codeB). Successfully completing this process results in logging in a user.

Implementation

The SSO flow involves generating codeA, exchanging it for codeB, and completing the authentication process with codeB. This ensures secure and efficient authentication for registered users.

import OpenWeb from 'react-native-openweb-sdk';

async function authenticateUser(username: string, password: string, userToken: string) {
  try {

    // Step 1: Initiate SSO flow - generates codeA
    const codeA = await OpenWeb.manager.authentication.startSSO();
    
    // Step 2: Send codeA to your backend to exchange for codeB
    // Your backend should call OpenWeb's /sso/v1/register-user endpoint
    const response = await fetch('https://your-backend.com/api/sso-exchange', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ 
        codeA, 
        username, 
        userToken 
      })
    });
    
    const { codeB } = await response.json();
    
    // Step 3: Complete SSO authentication with codeB
    const userId = await OpenWeb.manager.authentication.completeSSO(codeB);
    
    console.log('User authenticated successfully:', userId);
    return userId;
  } catch (error) {
    console.error('SSO authentication failed:', error);
    throw error;
  }
}

💡If the user is already known and has saved persistence on the publisher's end, the user can be automatically logged into the publisher system and then logged in through the OWAuthentication SSO methods.

StartSSO

Initiates the OpenWeb SSO authentication flow.

  • This generates a session ID (codeA) that should be sent to your backend for user registration with OpenWeb's authentication service.
  • @returns Promise resolving to the codeA session ID
  • @throws OWError if SSO initialization fails
async startSSO(): Promise<string>

CompleteSSO

Completes the OpenWeb SSO authentication flow.

  • Call this after your backend has validated the user and received codeB from OpenWeb's registration API.
  • @param codeB - The code received from OpenWeb's backend after user registration
  • @returns Promise resolving to the userId
  • @throws OWError if codeB is invalid or SSO completion fails
async completeSSO(codeB: string): Promise<string>

Third-party provider SSO

Third-party provider SSO is a simplified authentication method that allows users to log in using JWT tokens from supported identity providers (Auth0, Janrain, Gigya, Piano, Foxid, or Hearst), without requiring the standard two-step SSO handshake. This eliminates the need to exchange codeA for codeB through your backend.

  • @param provider - The SSO provider configuration (e.g., { type: OWSSOProviderType.Auth0 })
  • @param token - The authentication token from the provider
  • @returns Promise resolving to the userId
  • @throws OWError if provider authentication fails.
import OpenWeb, { OWSSOProviderType } from 'react-native-openweb-sdk';

async function authenticateWithProvider(providerToken: string) {
  try {
    // Authenticate using a third-party SSO provider
    const userId = await OpenWeb.manager.authentication.ssoUsingProvider(
      { type: OWSSOProviderType.Auth0 }, // or Janrain, Gigya, Piano, Foxid, Hearst
      providerToken
    );
    
    console.log('User authenticated via provider:', userId);
    return userId;
  } catch (error) {
    const { type, message } = error;
    console.error('Provider SSO failed:', type, message);
  }
}

Actions Requiring Login (onDisplayAuthenticationFlow)

In some scenarios, you may need to trigger a login interface before a user can perform an action, such as posting or replying to a comment.

Authentication must be completed in the following way:

  1. The app displays the React Native SDK UI.
  2. The unauthenticated user attempts to perform an action that requires login, such as posting, liking, or disliking a comment.
  3. The onDisplayAuthenticationFlow handler is triggered, prompting the app to present a login UI.
  4. The user logs in using the app credentials.
  5. The app's backend validates the user.
  6. The app initiates the SSO authentication flow using startSSO() and completeSSO() as described above.
  7. Upon successful SSO authentication, the app calls the completion callback to dismiss the login UI.
import OpenWeb from 'react-native-openweb-sdk';

// Register handler to display authentication when user attempts login-required actions
OpenWeb.manager.authentication.onDisplayAuthenticationFlow((completion) => {
  // Present your login UI here

  // Only call completion() after the user has successfully logged in
  completion();
});

Renew SSO

Regardless of the SSO approach used, you must implement OWRenewSSOCallback.

Renewing SSO ensures uninterrupted user connectivity. It is triggered when the existing authenticator for a previously connected user becomes invalid. This process silently re-establishes the user's connection without requiring any direct action.

import OpenWeb from 'react-native-openweb-sdk';

// Register a handler for SSO renewal requests
OpenWeb.manager.authentication.onRenewSSO(async (userId, completion) => {
  // Re-authenticate the user
  // Step 1: Start SSO flow
  const codeA = await OpenWeb.manager.authentication.startSSO();
   // Step 2: Exchange codeA for codeB with your backend

  const codeB = await getCodeBFromBackend(codeA, userId);
  // Step 3: Complete SSO authentication

  await OpenWeb.manager.authentication.completeSSO(codeB);
  
  // Always call completion when done
  completion();
});

Logout

Log out the currently authenticated user.

  • @returns Promise that resolves when logout is complete.
  • @throws OWError if logout operation fails.
import OpenWeb, { OWErrorType } from 'react-native-openweb-sdk';

async function handleLogout() {
  try {
    await OpenWeb.manager.authentication.logout();
    console.log('Logged out successfully');
  } catch (error) {
    const { type, message } = error;
    console.error('Logout failed:', type, message);
    // Handle the error / Show appropriate user UI
  }
}

User Status

Retrieve the current authentication status of the user (not authenticated, guest, or SSO logged in).

  • @returns Promise resolving to the user's authentication status.
  • @throws OWError if status check fails.
import OpenWeb, { OWErrorType } from 'react-native-openweb-sdk';

async function getUserStatus() {
  try {
    const status = await OpenWeb.manager.authentication.getUserStatus();
    console.log('User status:', status);
    return status;
  } catch (error) {
    const { type, message } = error;
    console.error('Get user status failed:', type, message);
  }
}

Login Prompts for Guests

You can control whether a login prompt is displayed for guest users in the full conversation view using the shouldDisplayLoginPrompt property.

getShouldDisplayLoginPrompt(): boolean;
setShouldDisplayLoginPrompt(value: boolean): void;

OWError

export const OWErrorType = {
  MissingSpotId: 'missingSpotId',
  SSOStart: 'ssoStart',
  SSOComplete: 'ssoComplete',
  SSOProvider: 'ssoProvider',
  AlreadyLoggedIn: 'alreadyLoggedIn',
  InvalidSpotId: 'invalidSpotId',
  Logout: 'logout',
  UserStatus: 'userStatus',
  Custom: 'custom',
} as const;

export type OWError =
  | { type: typeof OWErrorType.MissingSpotId; message: string }
  | { type: typeof OWErrorType.SSOStart; message: string }
  | { type: typeof OWErrorType.SSOComplete; message: string }
  | { type: typeof OWErrorType.SSOProvider; message: string }
  | { type: typeof OWErrorType.AlreadyLoggedIn; message: string }
  | { type: typeof OWErrorType.InvalidSpotId; message: string }
  | { type: typeof OWErrorType.Logout; message: string }
  | { type: typeof OWErrorType.UserStatus; message: string }
  | { type: typeof OWErrorType.Custom; message: string };