Heim > Web-Frontend > js-Tutorial > Single Sign-On (SSO): Eine umfassende Anleitung mit React und ExpressJS

Single Sign-On (SSO): Eine umfassende Anleitung mit React und ExpressJS

Susan Sarandon
Freigeben: 2025-01-06 01:17:07
Original
894 Leute haben es durchsucht

Single Sign-On (SSO) ist ein Authentifizierungsmechanismus, der es Benutzern ermöglicht, sich einmal anzumelden und auf mehrere verbundene Anwendungen oder Systeme zuzugreifen, ohne sich für jede einzelne erneut authentifizieren zu müssen. SSO zentralisiert die Benutzerauthentifizierung in einem einzigen, vertrauenswürdigen System (oft als Identitätsanbieter oder IdP bezeichnet), das dann Anmeldeinformationen verwaltet und Token oder Sitzungsdaten ausgibt, um die Identität des Benutzers bei anderen Diensten (sogenannten Dienstanbietern oder SPs) zu überprüfen.

In diesem Leitfaden untersuchen wir die Funktionsweise von SSO, seine Vor- und Nachteile, häufige Anwendungsfälle und Beispiele für die SSO-Implementierung in einer API (Node.js mit Express), einer Hauptanwendung (React) und einer externen Anwendung (Reagieren). Durch das Verständnis der Prinzipien und Praktiken von SSO können Unternehmen die Benutzererfahrung, Sicherheit und betriebliche Effizienz in ihren Anwendungen und Systemen verbessern.

Inhaltsverzeichnis

  • Single Sign-On (SSO)
    • Wie funktioniert SSO?
    • Vorteile von SSO
    • Nachteile von SSO
    • Anwendungsfälle für SSO
    • SSO-Implementierungsbeispiele
    • 1. API (Node.js mit Express)
    • 2. Hauptanwendung (Reagieren)
    • 3. Externe Anwendung (Reagieren)
  • Fazit

Links

  • GitHub-Repository

Demo-Video

Single Sign-On (SSO): A Comprehensive Guide with React and ExpressJS

Single Sign-On (SSO)

Single Sign-On (SSO) ist ein Authentifizierungsmechanismus, der es Benutzern ermöglicht, sich einmal anzumelden und Zugriff auf mehrere verbundene Anwendungen oder Systeme zu erhalten, ohne sich für jede einzelne erneut authentifizieren zu müssen.

SSO zentralisiert die Benutzerauthentifizierung in einem einzigen, vertrauenswürdigen System (oft als Identitätsanbieter oder IdP bezeichnet), das dann Anmeldeinformationen verwaltet und Token oder Sitzungsdaten ausgibt, um die Identität des Benutzers bei anderen Diensten (sogenannten Dienstanbietern oder SPs) zu überprüfen ).

Wie funktioniert SSO?

SSO funktioniert über sichere tokenbasierte Mechanismen wie OAuth 2.0, OpenID Connect (OIDC) oder Security Assertion Markup Language (SAML). Hier ist ein vereinfachter Ablauf:

  • Benutzeranmeldung: Der Benutzer gibt seine Anmeldeinformationen beim Identitätsanbieter (IdP) ein.

  • Token-Ausstellung: Der IdP validiert die Anmeldeinformationen und stellt ein Authentifizierungstoken aus (z. B. JWT- oder SAML-Assertion).

  • Dienstzugriff: Das Token wird an die Dienstanbieter weitergegeben, die es validieren und Zugriff gewähren, ohne dass weitere Anmeldungen erforderlich sind.

Vorteile von SSO

  • Verbesserte Benutzererfahrung: Benutzer können mit einem einzigen Login auf mehrere Dienste zugreifen, was Reibungsverluste reduziert und die Benutzerfreundlichkeit verbessert.

  • Verbesserte Sicherheit:

    • Reduziert die Passwortmüdigkeit, die zu unsicheren Praktiken wie der Wiederverwendung von Passwörtern führen kann.
    • Zentrale Authentifizierung ermöglicht strengere Passwortrichtlinien und die Durchsetzung der Multi-Faktor-Authentifizierung (MFA).
  • Vereinfachte Benutzerverwaltung:

    • Für Administratoren ist es einfacher, den Benutzerzugriff über verbundene Anwendungen hinweg zu verwalten.
    • Wenn Sie einem Benutzer den Zugriff vom IdP entziehen, wird dessen Zugriff auf alle integrierten Systeme deaktiviert.
  • Zeit- und Kosteneffizienz:

    • Spart Zeit für Benutzer und Support-Teams, indem Anmelde-bezogene Helpdesk-Anfragen reduziert werden.
    • Reduziert Entwicklungszeit und -kosten durch Nutzung vorhandener Authentifizierungsmechanismen.
  • Compliance und Auditing:

    • Zentrale Authentifizierung und Zugriffskontrolle erleichtern die Durchsetzung von Sicherheitsrichtlinien und die Verfolgung von Benutzeraktivitäten.

Nachteile von SSO

  • Single Point of Failure:

    • Wenn der IdP nicht verfügbar oder gefährdet ist, können Benutzer nicht auf verbundene Systeme zugreifen.
    • Abhilfe: Verwenden Sie redundante IdPs und stellen Sie eine hohe Verfügbarkeit sicher.
  • Komplexe Implementierung:

    • Die Integration von SSO erfordert umfangreiche Planung und Fachwissen, insbesondere in Umgebungen mit unterschiedlichen Anwendungen und Protokollen.
    • Abwehr: Nutzen Sie etablierte Protokolle wie OAuth 2.0 oder SAML und robuste SSO-Bibliotheken.
  • Sicherheitsrisiken:

    • Wenn ein Angreifer Zugriff auf die SSO-Anmeldeinformationen des Benutzers erhält, kann er möglicherweise auf alle verbundenen Systeme zugreifen.
    • Abwehr: Erzwingen Sie eine starke MFA und überwachen Sie verdächtige Anmeldeaktivitäten.
  • Vendor Lock-In:

    • Organisationen sind möglicherweise stark auf einen bestimmten IdP-Anbieter angewiesen, was die Migration zu einer Herausforderung macht.
    • Abhilfe: Wählen Sie offene Standards und vermeiden Sie proprietäre Lösungen.
  • Herausforderungen bei der Token-Verwaltung:

    • Abgelaufene oder gestohlene Token können den Zugriff stören oder Sicherheitslücken schaffen.
    • Abhilfe: Token-Ablauf, Aktualisierungsmechanismen und sichere Token-Speicherung implementieren.

Anwendungsfälle für SSO

  • Unternehmensanwendungen:

    • Mitarbeiter können mit einem einzigen Login auf verschiedene interne Tools und Dienste zugreifen.
    • Vereinfacht Onboarding- und Offboarding-Prozesse.
  • Cloud-Dienste:

    • Benutzer können ohne wiederholte Anmeldungen nahtlos zwischen Cloud-Anwendungen wechseln.
    • Verbessert die Produktivität und das Benutzererlebnis.
  • Kundenportale:

    • Bietet ein einheitliches Anmeldeerlebnis für Kunden verschiedener Dienste.
    • Ermöglicht Personalisierung und gezieltes Marketing.
  • Partnerintegration:

    • Erleichtert den sicheren Zugriff auf gemeinsame Ressourcen zwischen Partnerorganisationen.
    • Optimiert die Zusammenarbeit und den Datenaustausch.

SSO-Implementierungsbeispiele

1. API (Node.js mit Express)

Die API fungiert als Identitätsanbieter (IdP). Es authentifiziert Benutzer und stellt JWT-Tokens für den Zugriff aus.

Unten finden Sie eine strukturierte Aufschlüsselung des bereitgestellten Codes, in der den Zweck jedes Abschnitts für Ihre Follower erläutert wird. Dies dient als solides Beispiel für die Implementierung der SSO-Funktionalität in der API-Ebene.

Setup und Abhängigkeiten

Die folgenden Pakete werden in diesem Setup verwendet:

  • Express: Zur Bearbeitung von HTTP-Anfragen und Routing.
  • jsonwebtoken: Zum Generieren und Überprüfen von JWTs.
  • cors: Zur Bearbeitung ursprungsübergreifender Anfragen von verschiedenen Clientanwendungen.
  • @faker-js/faker: Zum Generieren von Scheinbenutzer- und Aufgabendaten.
  • Cookie-Parser: Zum Parsen von in Anfragen gesendeten Cookies.
  • dotenv: Zum sicheren Laden von Umgebungsvariablen.
Konfiguration
  • dotenv wird verwendet, um den geheimen Schlüssel sicher zu verwalten.
  • Für Entwicklungsumgebungen wird ein Fallback-Geheimnis bereitgestellt.
dotenv.config();
const SECRET_KEY = process.env.SECRET_KEY || "secret";
Nach dem Login kopieren
Nach dem Login kopieren
Middleware
  • CORS stellt sicher, dass Anfragen von bestimmten Front-End-Ursprüngen (Haupt- und externe App) zulässig sind.
  • cookieParser analysiert von Kunden gesendete Cookies.
  • express.json ermöglicht das Parsen von JSON-Anfragetexten.
app.use(
  cors({
    origin: ["http://localhost:5173", "http://localhost:5174"],
    credentials: true,
  })
);
app.use(express.json());
app.use(cookieParser());
Nach dem Login kopieren
Nach dem Login kopieren

Benutzerauthentifizierung und Token-Generierung

Mock-Daten simulieren Benutzer und die damit verbundenen Aufgaben.

Benutzer haben Rollen (Administrator oder Benutzer) und grundlegende Profilinformationen.
Todos sind für den personalisierten Zugriff mit Benutzer-IDs verknüpft.

  • /login: Authentifiziert Benutzer anhand von E-Mail und Passwort.

Benutzer erhalten nach erfolgreicher Anmeldung ein Cookie (sso_token), das das JWT enthält.
Dieses Token ist sicher, nur HTTP und zeitlich begrenzt, um Manipulationen zu verhindern.

app.post("/login", (req, res) => {
  const { email, password } = req.body;
  const user = users.find(
    (user) => user.email === email && user.password === password
  );

  if (user) {
    const token = jwt.sign({ user }, SECRET_KEY, { expiresIn: "1h" });
    res.cookie("sso_token", token, {
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      maxAge: 3600000,
      sameSite: "strict",
    });
    res.json({ message: "Login successful" });
  } else {
    res.status(400).json({ error: "Invalid credentials" });
  }
});
Nach dem Login kopieren
Nach dem Login kopieren
  • /verify: Validiert die Identität des Benutzers durch Dekodierung des Tokens. Ungültige Token führen zu einer nicht autorisierten Antwort.
app.get("/verify", (req, res) => {
  const token = req.cookies.sso_token;

  if (!token) {
    return res.status(401).json({ authenticated: false });
  }

  try {
    const decoded = jwt.verify(token, SECRET_KEY);
    res.json({ authenticated: true, user: decoded });
  } catch {
    res.status(401).json({ authenticated: false, error: "Invalid token" });
  }
});
Nach dem Login kopieren
Nach dem Login kopieren
  • /logout: Löscht das Cookie, das das JWT-Token enthält.

Stellt sicher, dass Benutzer sich sicher abmelden können, indem sie ihr Token löschen.

dotenv.config();
const SECRET_KEY = process.env.SECRET_KEY || "secret";
Nach dem Login kopieren
Nach dem Login kopieren
  • /todos: Ruft Todos ab, die dem authentifizierten Benutzer zugeordnet sind.
app.use(
  cors({
    origin: ["http://localhost:5173", "http://localhost:5174"],
    credentials: true,
  })
);
app.use(express.json());
app.use(cookieParser());
Nach dem Login kopieren
Nach dem Login kopieren
  • /todos: Fügt eine neue Aufgabe für den authentifizierten Benutzer hinzu.
app.post("/login", (req, res) => {
  const { email, password } = req.body;
  const user = users.find(
    (user) => user.email === email && user.password === password
  );

  if (user) {
    const token = jwt.sign({ user }, SECRET_KEY, { expiresIn: "1h" });
    res.cookie("sso_token", token, {
      httpOnly: true,
      secure: process.env.NODE_ENV === "production",
      maxAge: 3600000,
      sameSite: "strict",
    });
    res.json({ message: "Login successful" });
  } else {
    res.status(400).json({ error: "Invalid credentials" });
  }
});
Nach dem Login kopieren
Nach dem Login kopieren
  • /todos/:id: Aktualisiert eine Aufgabe basierend auf der angegebenen ID.
app.get("/verify", (req, res) => {
  const token = req.cookies.sso_token;

  if (!token) {
    return res.status(401).json({ authenticated: false });
  }

  try {
    const decoded = jwt.verify(token, SECRET_KEY);
    res.json({ authenticated: true, user: decoded });
  } catch {
    res.status(401).json({ authenticated: false, error: "Invalid token" });
  }
});
Nach dem Login kopieren
Nach dem Login kopieren
  • /todos/:id: Löscht eine Aufgabe basierend auf der angegebenen ID.
app.post("/logout", (req, res) => {
  res.clearCookie("sso_token");
  res.json({ message: "Logout successful" });
});
Nach dem Login kopieren

2. Hauptanwendung (React)

Die Hauptanwendung fungiert als Dienstanbieter (SP), der die API nutzt und Benutzerinteraktionen verwaltet.

Unten finden Sie eine strukturierte Aufschlüsselung des bereitgestellten Codes, in der den Zweck jedes Abschnitts für Ihre Follower erläutert wird. Dies dient als solides Beispiel für die Implementierung der SSO-Funktionalität in der Hauptanwendungsschicht.

  • App-Komponente

Die App-Komponente verwaltet die Benutzerauthentifizierung und Weiterleitungen basierend auf dem Anmeldestatus.

app.get("/todos/:userId", (req, res) => {
  const ssoToken = req.cookies.sso_token;
  const user = getUser(ssoToken);

  if (!user) {
    return res.status(401).json({ error: "Unauthorized" });
  }

  const userTodos = todos.filter((todo) => todo.userId === user.id);
  res.json(userTodos);
});
Nach dem Login kopieren
  • Anmeldekomponente

Die Login-Komponente übernimmt die Benutzeranmeldung und leitet bei erfolgreicher Authentifizierung zur Todos-Seite weiter.

app.post("/todos", (req, res) => {
  const ssoToken = req.cookies.sso_token;
  const user = getUser(ssoToken);

  if (!user) {
    return res.status(401).json({ error: "Unauthorized" });
  }

  const { title, description } = req.body;
  const newTodo = {
    id: faker.string.uuid(),
    userId: user.id,
    title,
    description,
  };

  todos.push(newTodo);
  res.status(201).json({ message: "Todo added successfully", data: newTodo });
});
Nach dem Login kopieren
  • Todos-Komponente

Die Todos-Komponente zeigt benutzerspezifische Todos an und ermöglicht das Hinzufügen und Löschen von Todos.

// Update a todo
app.put("/todos/:id", (req, res) => {
  const ssotoken = req.cookies.sso_token;
  const user = getUser(ssotoken);
  if (!user) {
    return res.status(401).json({ message: "Unauthorized" });
  }

  const { id } = req.params;
  const { title, description } = req.body;
  const index = todos.findIndex((todo) => todo.id === id);

  if (index !== -1) {
    todos[index] = {
      ...todos[index],
      title,
      description,
    };
    res.json({
      message: "Todo updated successfully",
      data: todos[index],
    });
  } else {
    res.status(404).json({ message: "Todo not found" });
  }
});
Nach dem Login kopieren

3. Externe Anwendung (Reagieren)

Die externe Anwendung fungiert als weiterer Dienstanbieter (SP), der die API nutzt und Benutzerinteraktionen verwaltet.

Unten finden Sie eine strukturierte Aufschlüsselung des bereitgestellten Codes, in der den Zweck jedes Abschnitts für Ihre Follower erläutert wird. Dies dient als solides Beispiel für die Implementierung der SSO-Funktionalität in der externen Anwendungsschicht.

  • App-Komponente

Die App-Komponente verwaltet die Benutzerauthentifizierung und Weiterleitungen basierend auf dem Anmeldestatus.

// Delete a todo
app.delete("/todos/:id", (req, res) => {
  const ssoToken = req.cookies.sso_token;
  const user = getUser(ssoToken);
  if (!user) {
    return res.status(401).json({ message: "Unauthorized" });
  }

  const { id } = req.params;
  const index = todos.findIndex((todo) => todo.id === id);

  if (index !== -1) {
    todos = todos.filter((todo) => todo.id !== id);
    res.json({ message: "Todo deleted successfully" });
  } else {
    res.status(404).json({ message: "Todo not found" });
  }
});
Nach dem Login kopieren
  • Todos-Komponente

Die Todos-Komponente zeigt benutzerspezifische Todos an.

import { useState, useEffect } from "react";
import {
  Navigate,
  Route,
  Routes,
  useNavigate,
  useSearchParams,
} from "react-router-dom";
import Todos from "./components/Todos";
import Login from "./components/Login";
import { toast } from "react-toastify";
import api from "./api";

function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();

  useEffect(() => {
    const verifyLogin = async () => {
      const returnUrl = searchParams.get("returnUrl");
      try {
        const response = await api.get("/verify", {
          withCredentials: true,
        });
        if (response.data.authenticated) {
          setIsLoggedIn(true);
          toast.success("You are logged in.");
          navigate("/todos");
        } else {
          setIsLoggedIn(false);
          if (!returnUrl) {
            toast.error("You are not logged in.");
          }
        }
      } catch (error) {
        setIsLoggedIn(false);
        console.error("Verification failed:", error);
      }
    };

    verifyLogin();

    const handleVisibilityChange = () => {
      if (document.visibilityState === "visible") {
        verifyLogin();
      }
    };

    document.addEventListener("visibilitychange", handleVisibilityChange);

    return () => {
      document.removeEventListener("visibilitychange", handleVisibilityChange);
    };
  }, [navigate, searchParams]);

  return (
    <div className="container p-4 mx-auto">
      <Routes>
        <Route path="/" element={<Login />} />
        <Route
          path="/todos"
          element={isLoggedIn ? <Todos /> : <Navigate to={"/"} />}
        />
      </Routes>
    </div>
  );
}

export default App;
Nach dem Login kopieren

Abschluss

Single Sign-On (SSO) vereinfacht die Benutzerauthentifizierung und Zugriffsverwaltung über mehrere Anwendungen hinweg und verbessert so das Benutzererlebnis, die Sicherheit und die betriebliche Effizienz. Durch die Zentralisierung der Authentifizierung und die Nutzung sicherer tokenbasierter Mechanismen können Unternehmen den Benutzerzugriff optimieren, passwortbezogene Risiken reduzieren und Compliance- und Prüffunktionen verbessern.

Während SSO zahlreiche Vorteile bietet, birgt es auch Herausforderungen wie Single Points of Failure, komplexe Implementierungsanforderungen, Sicherheitsrisiken und eine potenzielle Anbieterbindung. Unternehmen müssen SSO-Lösungen sorgfältig planen und implementieren, um diese Risiken zu mindern und die Vorteile der zentralisierten Authentifizierung zu maximieren.

Durch die Befolgung von Best Practices, die Nutzung etablierter Protokolle und die Wahl offener Standards können Unternehmen SSO erfolgreich implementieren, um die Benutzererfahrung, Sicherheit und betriebliche Effizienz in ihren Anwendungen und Systemen zu verbessern.

Das obige ist der detaillierte Inhalt vonSingle Sign-On (SSO): Eine umfassende Anleitung mit React und ExpressJS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage