Authentication in React involves managing user state, protecting routes, handling tokens, and providing login/logout functionality across your app.
1. Auth Context — global authentication state:
1import { createContext, useContext, useState, useEffect, ReactNode } from "react";23interface User {4 id: string;5 name: string;6 email: string;7}89interface AuthContextType {10 user: User | null;11 loading: boolean;12 login: (email: string, password: string) => Promise<void>;13 logout: () => Promise<void>;14}1516const AuthContext = createContext<AuthContextType>(null!);1718function AuthProvider({ children }: { children: ReactNode }) {19 const [user, setUser] = useState<User | null>(null);20 const [loading, setLoading] = useState(true);2122 useEffect(() => {23 // Check for existing session on mount24 checkAuth()25 .then(setUser)26 .catch(() => setUser(null))27 .finally(() => setLoading(false));28 }, []);2930 const login = async (email: string, password: string) => {31 const response = await fetch("/api/auth/login", {32 method: "POST",33 headers: { "Content-Type": "application/json" },34 body: JSON.stringify({ email, password }),35 });36 if (!response.ok) throw new Error("Login failed");37 const { user } = await response.json();38 setUser(user);39 };4041 const logout = async () => {42 await fetch("/api/auth/logout", { method: "POST" });43 setUser(null);44 };4546 return (47 <AuthContext.Provider value={{ user, loading, login, logout }}>48 {children}49 </AuthContext.Provider>50 );51}5253function useAuth() {54 const context = useContext(AuthContext);55 if (!context) throw new Error("useAuth must be used within AuthProvider");56 return context;57}
2. Protected Routes — prevent unauthorized access:
1import { Navigate, Outlet } from "react-router-dom";23function ProtectedRoute() {4 const { user, loading } = useAuth();56 if (loading) return <div className="spinner" />;7 if (!user) return <Navigate to="/login" replace />;89 return <Outlet />;10}1112// Route configuration13function App() {14 return (15 <AuthProvider>16 <BrowserRouter>17 <Routes>18 <Route path="/login" element={<LoginPage />} />19 <Route element={<ProtectedRoute />}>20 <Route path="/dashboard" element={<Dashboard />} />21 <Route path="/settings" element={<Settings />} />22 </Route>23 </Routes>24 </BrowserRouter>25 </AuthProvider>26 );27}
3. Custom hook — useRequireAuth:
1function useRequireAuth(redirectTo = "/login") {2 const { user, loading } = useAuth();3 const navigate = useNavigate();45 useEffect(() => {6 if (!loading && !user) {7 navigate(redirectTo, { replace: true });8 }9 }, [user, loading, redirectTo, navigate]);1011 return { user, loading, isAuthenticated: !!user };12}
Security best practices: