Protected Routes: Login-geschützte Seiten in React
Protected Routes in React Router
~12 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Unser Login-Knopf aus Kapitel 11 hat bisher keine echte Konsequenz. Jetzt bauen wir eine richtige Login-Seite UND einen Konto-Bereich, der nur für angemeldete Nutzer erreichbar ist – eine "Protected Route" (geschützte Route).
Das Prinzip: eine Wächter-Komponente
React Router hat kein eingebautes "Protected Route"-Konzept – das Muster ist stattdessen eine ganz normale, selbst gebaute Komponente, die prüft, ob der Nutzer angemeldet ist, und je nach Ergebnis entweder die eigentliche Seite ODER eine Weiterleitung zur Login-Seite rendert.
components/ProtectedRoute.jsx anlegen
import { Navigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
function ProtectedRoute({ children }) {
const { user } = useAuth();
if (!user) {
return <Navigate to="/login" replace />;
}
return children;
}
export default ProtectedRoute;<Navigate to="/login" replace /> ist die deklarative Art, in JSX eine Weiterleitung auszulösen (das Gegenstück zu useNavigate() aus Kapitel 18, nur als Komponente statt als Funktion). replace ersetzt den aktuellen Browser-Verlaufseintrag statt einen neuen hinzuzufügen – ohne replace würde der "Zurück"-Button den Nutzer zur geschützten (und sofort wieder verweigerten) Seite zurückführen.
pages/LoginPage.jsx anlegen
Ein echtes Login-Formular, das nach erfolgreichem "Login" zur Startseite weiterleitet:
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
function LoginPage() {
const [username, setUsername] = useState('');
const { login } = useAuth();
const navigate = useNavigate();
function handleSubmit(event) {
event.preventDefault();
if (username.trim() === '') {
return;
}
login(username);
navigate('/account');
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="username">Benutzername</label>
<input
id="username"
value={username}
onChange={(event) => setUsername(event.target.value)}
/>
<button type="submit">Anmelden</button>
</form>
);
}
export default LoginPage;pages/AccountPage.jsx anlegen (die geschützte Seite)
import { useAuth } from '../context/AuthContext';
function AccountPage() {
const { user, logout } = useAuth();
return (
<div>
<h2>Willkommen zurück, {user.username}!</h2>
<p>Das ist Ihr persönlicher Kontobereich.</p>
<button onClick={logout}>Abmelden</button>
</div>
);
}
export default AccountPage;App.jsx: die neuen Routen ergänzen
// Neue Imports:
import LoginPage from './pages/LoginPage';
import AccountPage from './pages/AccountPage';
import ProtectedRoute from './components/ProtectedRoute';
// Neue Routen innerhalb von <Routes>:
<Route path="/login" element={<LoginPage />} />
<Route
path="/account"
element={
<ProtectedRoute>
<AccountPage />
</ProtectedRoute>
}
/>Rufen Sie /account auf, OHNE angemeldet zu sein: Sie landen automatisch auf /login. Melden Sie sich an: Sie landen auf /account und sehen den geschützten Inhalt. ProtectedRoute ist absichtlich generisch geschrieben – Sie könnten damit beliebig viele weitere geschützte Seiten umschließen, ohne die Prüf-Logik zu wiederholen.
Achtung: Diese Art des Schutzes läuft komplett im Browser und ist NICHT sicherheitskritisch – ein technisch versierter Nutzer könnte den JavaScript-Code umgehen und die Seite trotzdem im Speicher haben. Echte Absicherung von Daten (nicht nur der Anzeige) muss IMMER serverseitig passieren – die React-Seite darf zwar entscheiden, WAS sie anzeigt, aber niemals der einzige Schutz für tatsächlich sensible Daten sein.