Overview
The AuthGuard component is a higher-order component that wraps protected routes to ensure only authenticated users can access them. It integrates with Auth0 to check authentication status and handles loading, unauthenticated, and error states.
Source: src/components/AuthGuard.tsx
Key Features
- Checks user authentication status before rendering protected content
- Displays loading spinner during authentication check
- Redirects unauthenticated users to login page
- Handles authentication errors gracefully
- Seamlessly renders protected component when authenticated
Props
The component accepts a single prop defined by the AuthGuardProps interface:
component
React.ReactElement
required
The protected component to render when the user is authenticated.
TypeScript Interface
interface AuthGuardProps {
component: React.ReactElement;
}
Authentication States
AuthGuard handles four distinct authentication states:
1. Loading State
While Auth0 is checking authentication status, a centered loading spinner is displayed:
if (isLoading) {
return (
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
<CircularProgress />
</Box>
);
}
2. Unauthenticated State
If the user is not authenticated, they are redirected to the Login component:
if (!isAuthenticated) {
console.log('User is not authenticated, redirecting to login');
return <Login />;
}
3. Error State
If an authentication error occurs, an error message is displayed:
if (error) {
return <div>Oops... {error.message}</div>;
}
4. Authenticated State
When successfully authenticated, the protected component is rendered:
Usage Examples
Basic Usage with React Router
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import AuthGuard from './components/AuthGuard';
import Dashboard from './pages/Dashboard';
import Settings from './pages/Settings';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/dashboard" element={
<AuthGuard component={<Dashboard />} />
} />
<Route path="/settings" element={
<AuthGuard component={<Settings />} />
} />
</Routes>
</BrowserRouter>
);
}
Protecting Multiple Routes
import AuthGuard from './components/AuthGuard';
import MasterLayout from './components/MasterLayout';
function App() {
return (
<Routes>
<Route path="/" element={
<AuthGuard component={<MasterLayout />} />
}>
{/* Nested routes are automatically protected */}
<Route path="dashboard" element={<Dashboard />} />
<Route path="api-tests" element={<ApiTesting />} />
</Route>
</Routes>
);
}
Custom Protected Page
import AuthGuard from './components/AuthGuard';
import MyProtectedPage from './pages/MyProtectedPage';
function ProtectedRoute() {
return (
<AuthGuard
component={
<MyProtectedPage
title="Protected Content"
data={myData}
/>
}
/>
);
}
Integration with Auth0
AuthGuard uses the useAuth0 hook to access authentication state:
const { isAuthenticated, isLoading, error } = useAuth0();
Required Setup
Ensure your app is wrapped with the Auth0 provider:
import { Auth0Provider } from '@auth0/auth0-react';
function App() {
return (
<Auth0Provider
domain="your-domain.auth0.com"
clientId="your-client-id"
authorizationParams={{
redirect_uri: window.location.origin
}}
>
<YourAppRoutes />
</Auth0Provider>
);
}
Material-UI Components
AuthGuard uses the following Material-UI components:
Box: Container for layout and styling
CircularProgress: Loading spinner during authentication check
Complete Source Code
import React from 'react';
import { useAuth0 } from '@auth0/auth0-react';
import { CircularProgress, Box } from '@mui/material';
import Login from './Login';
interface AuthGuardProps {
component: React.ReactElement;
}
const AuthGuard: React.FC<AuthGuardProps> = ({
component
}) => {
const { isAuthenticated, isLoading, error } = useAuth0();
if (isLoading) {
return (
<Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
<CircularProgress />
</Box>
);
}
if (!isAuthenticated) {
console.log('User is not authenticated, redirecting to login');
return <Login />;
}
if (error) {
return <div>Oops... {error.message}</div>;
}
return <>{component}</>;
};
export default AuthGuard;
Best Practices
- Wrap at Route Level: Apply AuthGuard at the route level rather than individual components
- Nested Protection: Protect parent routes to automatically protect all child routes
- Error Handling: Consider customizing the error UI for better user experience
- Loading State: The default loading spinner works well, but can be customized if needed
- Logging: Keep authentication logs for debugging purposes (already included)