React SDK
React components and hooks for OAuth 2.0 authentication with BinoAuth.
This SDK provides OAuth 2.0 authentication only. For other authentication flows, use the core binoauth SDK directly.
Installation
npm install @binoauth/reactQuick Start
Setup Provider
// App.tsx
import { AuthProvider } from '@binoauth/react';
function App() {
return (
<AuthProvider
clientId="your-client-id"
issuer="https://auth.binoauth.com"
redirectUri="http://localhost:3000/callback"
scope="openid profile email"
>
<YourApp />
</AuthProvider>
);
}Use Authentication
// Profile.tsx
import { useAuth } from '@binoauth/react';
function Profile() {
const { user, isLoading, isAuthenticated, login, logout } = useAuth();
if (isLoading) return <div>Loading...</div>;
if (!isAuthenticated) return <button onClick={login}>Login</button>;
return (
<div>
<h1>Welcome, {user?.name}</h1>
<button onClick={() => logout()}>Logout</button>
</div>
);
}Protect Routes
// Dashboard.tsx
import { ProtectedRoute } from '@binoauth/react';
function Dashboard() {
return (
<ProtectedRoute loadingFallback={<div>Loading...</div>}>
<div>Protected content</div>
</ProtectedRoute>
);
}Handle OAuth Callback
// CallbackPage.tsx
import { AuthCallbackPage } from '@binoauth/react';
function CallbackPage() {
return (
<AuthCallbackPage
onSuccess={() => {
// Redirect to dashboard or intended page
window.location.href = '/dashboard';
}}
onError={(error) => {
console.error('Auth error:', error);
// Handle error (show message, redirect to login, etc.)
}}
loadingComponent={<div>Processing authentication...</div>}
/>
);
}Components
AuthProvider
The main provider component that manages authentication state.
<AuthProvider
clientId="your-client-id"
issuer="https://auth.binoauth.com"
redirectUri="https://yourapp.com/callback"
scope="openid profile email"
>
<YourApp />
</AuthProvider>ProtectedRoute
Protects routes that require authentication.
<ProtectedRoute
loadingFallback={<Spinner />}
redirectTo="/login"
>
<SecretContent />
</ProtectedRoute>AuthCallbackPage
Handles OAuth callback processing.
<AuthCallbackPage
onSuccess={(user) => {
console.log('Logged in as:', user.name);
window.location.href = '/dashboard';
}}
onError={(error) => {
console.error('Login failed:', error);
window.location.href = '/login?error=auth_failed';
}}
loadingComponent={<div>Authenticating...</div>}
styles={{
container: 'auth-callback-container',
loading: 'auth-loading',
error: 'auth-error'
}}
/>AuthErrorBoundary
Handles authentication errors gracefully.
import { AuthErrorBoundary } from '@binoauth/react';
<AuthErrorBoundary
fallback={(error) => (
<div>
<h1>Authentication Error</h1>
<p>{error.message}</p>
<button onClick={() => window.location.reload()}>
Retry
</button>
</div>
)}
onError={(error, errorInfo) => {
console.error('Auth error:', error, errorInfo);
}}
>
<YourApp />
</AuthErrorBoundary>Hooks
useAuth
Main authentication hook providing auth state and methods.
const {
user, // User object or null
isLoading, // Loading state
isAuthenticated, // Authentication status
error, // Error state
login, // Login function
logout, // Logout function
callback, // Handle OAuth callback
getAccessToken, // Get access token
refreshToken // Refresh tokens
} = useAuth();Methods:
// Redirect to login
await login();
// Logout with optional redirect
await logout(); // Redirects to provider logout
await logout('/home'); // Redirects to /home after logout
// Handle OAuth callback
await callback(code, state);
// Get current access token
const token = await getAccessToken();
// Refresh tokens
await refreshToken();useAuthErrorHandler
Error handling utilities for authentication.
import { useAuthErrorHandler } from '@binoauth/react';
function MyComponent() {
const { error, handleError, clearError } = useAuthErrorHandler();
const handleApiCall = async () => {
try {
await someApiCall();
} catch (err) {
handleError(err);
}
};
if (error) {
return (
<div>
Error: {error.message}
<button onClick={clearError}>Retry</button>
</div>
);
}
return <div>Content</div>;
}Router Integration
React Router
// App.tsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { AuthProvider, ProtectedRoute } from '@binoauth/react';
function App() {
return (
<AuthProvider config={authConfig}>
<BrowserRouter>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route path="/callback" element={<AuthCallbackPage />} />
<Route path="/dashboard" element={
<ProtectedRoute>
<Dashboard />
</ProtectedRoute>
} />
</Routes>
</BrowserRouter>
</AuthProvider>
);
}Next.js App Router
// app/layout.tsx
import { AuthProvider } from '@binoauth/react';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html>
<body>
<AuthProvider config={authConfig}>
{children}
</AuthProvider>
</body>
</html>
);
}Configuration
Environment Variables
NEXT_PUBLIC_BINOAUTH_ISSUER=https://auth.binoauth.com
NEXT_PUBLIC_BINOAUTH_CLIENT_ID=your-client-id
NEXT_PUBLIC_BINOAUTH_REDIRECT_URI=https://yourapp.com/callbackconst config = {
issuer: process.env.NEXT_PUBLIC_BINOAUTH_ISSUER!,
clientId: process.env.NEXT_PUBLIC_BINOAUTH_CLIENT_ID!,
redirectUri: process.env.NEXT_PUBLIC_BINOAUTH_REDIRECT_URI!,
scope: 'openid profile email'
};Storage Configuration
const storageConfig = {
storage: 'localStorage', // 'localStorage', 'sessionStorage', 'memory'
encryptionKey: 'your-key', // Optional encryption key
secure: true, // Enhanced security features
prefix: 'myapp_auth' // Storage key prefix
};Security Features
- Client-Safe Configuration: Automatically generates secure storage keys
- Open Redirect Prevention: Validates all redirect URLs
- Token Encryption: Encrypts tokens in browser storage
- Error Boundaries: Isolates authentication errors
- CSRF Protection: Enhanced state validation
- Same-Origin Policy: Enforces same-origin redirects
Error Handling
⚠️
Always wrap your app with AuthErrorBoundary for production use.
import { AuthErrorBoundary } from '@binoauth/react';
function App() {
return (
<AuthErrorBoundary
fallback={(error) => <ErrorPage error={error} />}
onError={(error, errorInfo) => {
// Log to error reporting service
console.error('Auth error:', error, errorInfo);
}}
>
<AuthProvider config={config}>
<YourApp />
</AuthProvider>
</AuthErrorBoundary>
);
}TypeScript Support
The SDK is fully typed with TypeScript:
import type {
AuthContextType,
ClientSafeAuthConfig,
AuthCallbackPageProps,
User
} from '@binoauth/react';
import type {
BinoAuthConfig,
AuthConfig,
StorageConfig,
TokenResponse
} from 'binoauth';API Reference
Components
// AuthProvider
interface AuthProviderProps {
config: BinoAuthConfig | AuthConfig;
storageConfig?: StorageConfig;
children: ReactNode;
}
// ProtectedRoute
interface ProtectedRouteProps {
children: ReactNode;
loadingFallback?: ReactNode;
redirectTo?: string;
}
// AuthCallbackPage
interface AuthCallbackPageProps {
onSuccess?: (user: User) => void;
onError?: (error: Error) => void;
loadingComponent?: ReactNode;
styles?: AuthCallbackPageStyles;
}
// AuthErrorBoundary
interface AuthErrorBoundaryProps {
children: ReactNode;
fallback: (error: Error) => ReactNode;
onError?: (error: Error, errorInfo: ErrorInfo) => void;
}Hooks
// useAuth
interface AuthContextType {
user: User | null;
isLoading: boolean;
isAuthenticated: boolean;
error: Error | null;
login: () => Promise<void>;
logout: (returnTo?: string) => Promise<void>;
callback: (code: string, state: string) => Promise<void>;
getAccessToken: () => Promise<string | null>;
refreshToken: () => Promise<void>;
}
// useAuthErrorHandler
interface AuthErrorHandler {
error: Error | null;
handleError: (error: Error) => void;
clearError: () => void;
}Last updated on