Integrate Sessions With The Frontend (React)

Create a React Context to store the user's session state and protect authenticated routes.

Now that you've updated your server endpoints to manage the user's session, we'll next go over how to store that session data into your frontend using the React Client Auth SDK. We'll also show how to use the authenticated state from the SDK's React Context to protect routes that require authentication.


Install the React SDK

Install the React Client Auth SDK using your preferred package manager CLI:

npm install @wristband/react-client-auth
yarn add @wristband/react-client-auth
pnpm add @wristband/react-client-auth

Configure the SDK and Propagate Authenticated State

The SDK contains a WristbandAuthProvider component that establishes and manages authentication state throughout your React frontend. It will call the Session Endpoint that was implemented earlier to retrieve the user's session data. If the call to the Session Endpoint succeeds, we can be sure that the user has successfully authenticated, and any pertinent session data will be stored in the Provider's React Context. However, if the call to the Session Endpoint returns a 401 status code, then we know that the user does not have a valid session, and the user will be redirected to the Login Endpoint.

WristbandAuthProvider requires three URL endpoints:

  • loginUrl: The URL of your backend server's Login Endpoint.
  • logoutUrl: The URL of your backend server's Logout Endpoint.
  • sessionUrl: The URL of your backend server's Session Endpoint.

Place the WristbandAuthProvider at your app's root to ensure the user's authenticated state is available throughout your application and verified on initial load. Configure the component with the 3 URLs above.

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { WristbandAuthProvider } from '@wristband/react-client-auth';

import './index.css';

import { App } from 'app';

const root = createRoot(document.getElementById('root'));

root.render(
  <StrictMode>
    <WristbandAuthProvider
      loginUrl='/api/auth/login'
      logoutUrl='/api/auth/logout'
      sessionUrl='/api/session'
    >
      <App />
    </WristbandAuthProvider>
  </StrictMode>
);



Protect Frontend Routes and Components

The SDK exposes some hooks and utility functions that enable common patterns like conditional rendering of authenticated/unauthenticated views, route protection, or dynamic UI updates based on the user's auth status.

Hooks

  • useWristbandAuth(): Get access to the user's authentication state throughout your app.
  • useWristbandSession(): Get access to the user data provided by your backend server's Session Endpoint.

Utility Functions

  • redirectToLogin(): Redirects the user to your backend server's Login Endpoint.
  • redirectToLogout(): Redirects the user to your backend server's Logout Endpoint.

Below are several common patterns you can apply as needed.


Use The User's Authenticated State to Render Different Components

import React from 'react';

import { useWristbandAuth, useWristbandSession, redirectToLogin, redirectToLogout } from '@wristband/react-client-auth';

function App() {
  const { isAuthenticated, isLoading } = useWristbandAuth();
  const { userId, tenantId } = useWristbandSession();
  
  if (isLoading) {
    return <div>Loading...</div>;
  }

  const AuthenticatedView = () => (
    <>
      <h1>Welcome to Wristband Auth</h1>
      <p>Your User ID: {userId}</p>
      <p>Your Tenant ID: {tenantId}</p>
      <button onClick={() => redirectToLogout('/api/auth/logout')}>Logout</button>
    </>
  );
  const UnauthenticatedView = () => (
    <>
      <h1>Welcome to Wristband Auth</h1>
      <button onClick={() => redirectToLogin('/api/auth/login')}>Login</button>
    </>
  );

  return (
    <div>
      {isAuthenticated ? <AuthenticatedView /> : <UnauthenticatedView />}
    </div>
  );
};

export default App;


Create an AuthGuard Component to Protect Explicit Routes

import React from 'react';
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import { useWristbandAuth } from '@wristband/react-client-auth';

import { Dashboard, Login } from '@/components';

const AuthGuard = ({ children }: { children: React.ReactNode }) => {
  const { isAuthenticated, isLoading } = useWristbandAuth();
  
  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (!isAuthenticated) {
    return <Navigate to="/login" replace />;
  }

  return children;
};

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/login" element={<Login />} />
        <Route
          path="/dashboard"
          element={
            <AuthGuard>
              <Dashboard />
            </AuthGuard>
          }
        />
      </Routes>
    </BrowserRouter>
  );
}

export default App;


Congratulations on making it this far! You've now learned how to integrate Wristband authentication into both your Express server and React frontend!


What’s Next

Before we test the authentication flows, let's first determine if your application needs to configure CORS.