Metronic React
Getting Started

Authentication

Learn how to use the Supabase authentication system in Metronic React.

Authentication

Metronic React includes a complete authentication system powered by Supabase, providing user authentication, protected routes, and profile management.

Overview

The authentication system consists of:

  1. Auth Context: Provides authentication state and methods
  2. Supabase Provider: Connects to Supabase Authentication
  3. Supabase Adapter: Translates between the app and Supabase Auth API
  4. Protected Routes: Guards routes that require authentication
  5. Auth Helpers: Utilities for storing and retrieving tokens

File Structure

The authentication system is organized in the following structure:

src/auth/
├── adapters/             # Authentication backend adapters
│   └── supabase-adapter.ts  # Supabase implementation
├── context/              # Context definitions
│   └── auth-context.ts   # Auth context interface
├── forms/                # Authentication form components
├── layouts/              # Auth page layouts
├── lib/                  # Helper utilities
│   ├── helpers.ts        # Token management
│   └── models.ts         # Type definitions
├── pages/                # Auth pages (login, register, etc.)
├── providers/            # Context providers
│   └── supabase-provider.tsx # Supabase auth implementation
├── auth-context.ts       # Context export file
├── auth-routes.tsx       # Auth routes definition
├── auth-routing.tsx      # Auth routing component
└── require-auth.tsx      # Protected route component

Environment Setup

Configure your .env file with Supabase credentials:

VITE_SUPABASE_URL=your_supabase_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key

Usage Guide

Getting Started

To implement authentication in your application:

  1. Setup Supabase Project:

    • Create a Supabase project and obtain URL and anon key
    • Add these credentials to your .env file
  2. Auth Provider Setup:

    • The Auth Provider is already wrapped around your app in the main layout
    • No additional setup is needed for basic authentication
  3. Authentication Flow:

    • Redirect unauthenticated users to /auth/signin
    • Process login/registration via auth context methods
    • After successful auth, redirect to protected routes

Implementing Login

The login flow involves:

  1. Collecting credentials (email/password or social provider)
  2. Passing them to the auth context's login methods
  3. Handling success (redirect) or errors (display messages)
const { login, loading } = useAuthContext();
 
// Start login process when form is submitted
const handleLogin = async (email, password) => {
  try {
    await login(email, password);
    // Redirect happens automatically
  } catch (error) {
    // Handle error
  }
};

Protecting Routes and Content

Secure your application using:

  1. Route Protection: For entire routes/pages
  2. Component Guards: For specific UI elements
  3. Conditional Rendering: For inline protection

Route protection using router configuration:

// Routes are already protected in routing configuration
// <Route element={<RequireAuth />}>
//   <Route path="/dashboard" element={<Dashboard />} />
// </Route>

Conditional rendering in components:

function AdminAction() {
  const { isAdmin, currentUser } = useAuthContext();
 
  if (!currentUser) return null;
 
  return (
    <>
      {isAdmin && <button>Admin Action</button>}
    </>
  );
}

Managing User Profiles

User profiles can be accessed and updated:

  1. Display Profile: Show user data in components
  2. Edit Profile: Update user information
  3. Custom Fields: Store additional user metadata
// Display user info
const { currentUser } = useAuthContext();
const userName = currentUser?.fullname || `${currentUser?.first_name} ${currentUser?.last_name}`;
 
// Update profile
const { updateProfile } = useAuthContext();
await updateProfile({
  first_name: "Updated",
  last_name: "Name"
});

Authentication State in Components

Use authentication state to conditionally render UI:

function ProfileButton() {
  const { auth, loading } = useAuthContext();
 
  if (loading) return <LoadingSpinner />;
 
  return auth ? <UserDropdown /> : <LoginButton />;
}

Social Authentication

Implement social login with minimal code:

const { login } = useAuthContext();
 
// Get signInWithOAuth from SupabaseAdapter
const handleGoogleLogin = () => {
  SupabaseAdapter.signInWithOAuth('google');
};
 
// Supported providers: 'google', 'github', 'facebook', 'twitter', 'discord', 'slack'

Password Management

Implement password reset flows:

  1. Forgot Password: Send reset link
  2. Reset Password: Process reset form
  3. Change Password: Update existing password
// Request password reset
const { requestPasswordReset } = useAuthContext();
await requestPasswordReset(email);
 
// Reset password
const { resetPassword } = useAuthContext();
await resetPassword(newPassword, confirmPassword);
 
// Resend verification email
const { resendVerificationEmail } = useAuthContext();
await resendVerificationEmail(email);

Authentication Persistence

Authentication state persists across sessions:

  • Tokens stored in localStorage
  • Automatic token refresh
  • Session recovery on page reload

When a user closes the browser and returns later, their authentication state is automatically restored from localStorage, providing a seamless experience.

Authentication API

Auth Context

The useAuthContext hook provides access to authentication state and methods:

import { useAuthContext } from '@/auth/auth-context';
 
// Inside your component
const {
  currentUser,  // Current user data
  auth,         // Auth tokens
  loading,      // Auth loading state
  isAdmin,      // Admin status
  login,        // Login method
  register,     // Registration method
  logout,       // Logout method
  requestPasswordReset, // Password reset request
  resetPassword, // Password reset
  resendVerificationEmail, // Resend verification email
  updateProfile, // Update user profile
  getUser,      // Get current user data
  verify        // Verify auth state
} = useAuthContext();

Login Methods

Email/password authentication:

const { login } = useAuthContext();
 
// Login with email/password
await login(email, password);

Social authentication using the adapter:

import { SupabaseAdapter } from '@/auth/adapters/supabase-adapter';
 
// Social login (provider: 'google', 'github', 'facebook', 'twitter', 'discord', 'slack')
await SupabaseAdapter.signInWithOAuth(provider);

Registration

Register a new user:

const { register } = useAuthContext();
 
// Register user
await register(
  email,
  password,
  passwordConfirmation,
  firstName,  // optional
  lastName    // optional
);

Password Reset

Request password reset:

const { requestPasswordReset } = useAuthContext();
 
// Send password reset email
await requestPasswordReset(email);

Reset password:

const { resetPassword } = useAuthContext();
 
// Reset password
await resetPassword(password, passwordConfirmation);

Resend verification email:

const { resendVerificationEmail } = useAuthContext();
 
// Resend email verification
await resendVerificationEmail(email);

User Profile

Get and update user profile:

const { currentUser, updateProfile } = useAuthContext();
 
// Update profile
await updateProfile({
  first_name: "New",
  last_name: "Name",
  phone: "123456789",
  // Other profile fields
});

Logout

Sign out the current user:

const { logout } = useAuthContext();
 
// Log out user
await logout();

Protected Routes

The RequireAuth component protects routes that require authentication:

// In your routing configuration
<Routes>
  <Route element={<RequireAuth />}>
    {/* Protected routes */}
    <Route path="/dashboard" element={<Dashboard />} />
    <Route path="/profile" element={<Profile />} />
  </Route>
 
  {/* Public routes */}
  <Route path="/auth/*" element={<AuthRouting />} />
</Routes>

User Model

The authenticated user object includes:

interface UserModel {
  id: string;
  email: string;
  email_verified?: boolean;
  username?: string;
  first_name?: string;
  last_name?: string;
  fullname?: string;
  pic?: string;
  phone?: string;
  company_name?: string;
  companyName?: string; // For backward compatibility
  occupation?: string;
  roles?: string[];
  language?: string;
  is_admin?: boolean;
}

Authentication State Management

The authentication state is managed automatically:

  • Token storage in localStorage
  • Auto-refresh for expired tokens
  • Session verification
  • Redirect to login for unauthenticated requests

For more details on Supabase authentication, see the Supabase Auth documentation.