Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

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

src/components/ProtectedRoute.jsx
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:

src/pages/LoginPage.jsx
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)

src/pages/AccountPage.jsx
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.