Setup Guide
This guide provides a comprehensive setup of Reclaim Auth in your React application.
Configuration Setup
- Create a config file (
src/config/auth.config.ts
):
interface AuthConfig {
clientId: string;
redirectUri: string;
environment?: 'development' | 'production';
}
export const authConfig: AuthConfig = {
clientId: process.env.REACT_APP_RECLAIM_CLIENT_ID!,
clientSecret: process.env.REACT_APP_RECLAIM_CLIENT_SECRET!,
redirectUri: process.env.REACT_APP_RECLAIM_REDIRECT_URI!,
environment: process.env.NODE_ENV as 'development' | 'production'
};
Authentication Provider
Create an Auth Provider to manage authentication state throughout your application:
// src/providers/AuthProvider.tsx
import React, { createContext, useContext, useEffect, useState } from 'react';
import getReclaimAuth, { type ReclaimUser } from 'identity-react';
import { authConfig } from '../config/auth.config';
interface AuthContextType {
user: ReclaimUser | null;
loading: boolean;
error: Error | null;
signIn: () => Promise<void>;
signOut: () => Promise<void>;
}
const AuthContext = createContext<AuthContextType | null>(null);
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<ReclaimUser | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<Error | null>(null);
const auth = getReclaimAuth(authConfig.clientId, authConfig.clientSecret, authConfig.redirectUri);
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged((newUser) => {
setUser(newUser);
setLoading(false);
});
return () => unsubscribe();
}, []);
const signIn = async () => {
try {
setError(null);
await auth.signIn();
} catch (err) {
setError(err instanceof Error ? err : new Error('Authentication failed'));
throw err;
}
};
const signOut = async () => {
try {
setError(null);
await auth.signOut();
} catch (err) {
setError(err instanceof Error ? err : new Error('Sign out failed'));
throw err;
}
};
return (
<AuthContext.Provider
value={{
user,
loading,
error,
signIn,
signOut
}}
>
{children}
</AuthContext.Provider>
);
}
// Custom hook to use auth context
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
}
Application Setup
Wrap your application with the AuthProvider:
// src/App.tsx
import { AuthProvider } from './providers/AuthProvider';
function App() {
return (
<AuthProvider>
<Router>
<YourAppComponents />
</Router>
</AuthProvider>
);
}
Usage Example
Here's how to use the authentication in a component:
// src/components/Profile.tsx
import { useAuth } from '../providers/AuthProvider';
function Profile() {
const { user, loading, error, signIn, signOut } = useAuth();
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
if (!user) {
return (
<div>
<p>Please sign in to view your profile</p>
<button onClick={signIn}>Sign In</button>
</div>
);
}
return (
<div>
<h1>Profile</h1>
<p>ID: {user.id}</p>
<pre>{JSON.stringify(user.userData, null, 2)}</pre>
<pre>{JSON.stringify(user.additionalData, null, 2)}</pre>
<button onClick={signOut}>Sign Out</button>
</div>
);
}
TypeScript Support
The SDK includes TypeScript definitions:
interface ReclaimUser {
id: string;
userData: {
[key: string]: string;
}
additionalData: {
[key: string]: string;
}[];
}
interface AuthError extends Error {
code?: string;
details?: unknown;
}
Security Considerations
- Environment Variables: Always use environment variables for sensitive configuration:
REACT_APP_RECLAIM_CLIENT_ID=your_client_id
REACT_APP_RECLAIM_CLIENT_SECRET=your_client_secret,
REACT_APP_RECLAIM_REDIRECT_URI=http://localhost:3000
- CORS and CSP: Configure your Content Security Policy to allow popups:
<!-- public/index.html -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https://identity.reclaimprotocol.org; frame-src 'self' https://identity.reclaimprotocol.org">
- Error Handling: Always implement proper error handling for authentication flows:
try {
await auth.signIn();
} catch (error) {
if (error.message.includes('popup')) {
// Handle popup blocked
} else if (error.message.includes('unauthorized')) {
// Handle unauthorized client
} else {
// Handle other errors
}
}
Next Steps
- Authentication Hooks - Learn about custom hooks for authentication