Careeroza
Protected Routes
ProtectedRoute Component
With React Router 6, a protected route is a component that renders <Outlet /> (the child page) if the user is allowed, or redirects otherwise.
// src/auth/ProtectedRoute.jsx
import { Navigate, Outlet, useLocation } from 'react-router-dom';
import { useAuth } from './AuthContext';
export default function ProtectedRoute({ roles }) {
const { user } = useAuth();
const location = useLocation();
if (!user) {
// remember where the user wanted to go
return <Navigate to="/login" replace state={{ from: location }} />;
}
if (roles && !roles.some((r) => user.roles.includes(r))) {
return <Navigate to="/forbidden" replace />;
}
return <Outlet />;
}Routes
// src/App.jsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { AuthProvider } from './auth/AuthContext';
import ProtectedRoute from './auth/ProtectedRoute';
import HomePage from './pages/HomePage';
import LoginPage from './pages/LoginPage';
import OrdersPage from './pages/OrdersPage';
import SellerDashboard from './pages/SellerDashboard';
import AdminPage from './pages/AdminPage';
import ForbiddenPage from './pages/ForbiddenPage';
export default function App() {
return (
<AuthProvider>
<BrowserRouter>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/forbidden" element={<ForbiddenPage />} />
<Route element={<ProtectedRoute />}>
<Route path="/orders" element={<OrdersPage />} />
</Route>
<Route element={<ProtectedRoute roles={['ROLE_SELLER', 'ROLE_ADMIN']} />}>
<Route path="/seller" element={<SellerDashboard />} />
</Route>
<Route element={<ProtectedRoute roles={['ROLE_ADMIN']} />}>
<Route path="/admin" element={<AdminPage />} />
</Route>
</Routes>
</BrowserRouter>
</AuthProvider>
);
}Frontend Checks Are Not Security
Note: Anyone can open DevTools and edit shopease_user in localStorage to add ROLE_ADMIN. They would see the admin page, but every API call it makes would get 403, because the server checks the signed token. Route guards are for user experience; the real security is always on the server.