Maison > interface Web > js tutoriel > Authentification unique (SSO) : un guide complet avec React et ExpressJS

Authentification unique (SSO) : un guide complet avec React et ExpressJS

Susan Sarandon
Libérer: 2025-01-06 01:17:07
original
855 Les gens l'ont consulté

Single Sign-On (SSO) est un mécanisme d'authentification qui permet aux utilisateurs de se connecter une seule fois et d'accéder à plusieurs applications ou systèmes connectés sans avoir besoin de se réauthentifier pour chacun. SSO centralise l'authentification des utilisateurs dans un système unique et fiable (souvent appelé fournisseur d'identité ou IdP), qui gère ensuite les informations d'identification et émet des jetons ou des données de session pour vérifier l'identité de l'utilisateur sur d'autres services (appelés fournisseurs de services ou SP).

Dans ce guide, nous explorerons le fonctionnement du SSO, ses avantages et ses inconvénients, des cas d'utilisation courants et des exemples d'implémentation de SSO dans une API (Node.js avec Express), une application principale (React) et une application externe. application (Réagir). En comprenant les principes et les pratiques du SSO, les organisations peuvent améliorer l'expérience utilisateur, la sécurité et l'efficacité opérationnelle dans leurs applications et systèmes.

Table des matières

  • Authentification unique (SSO)
    • Comment fonctionne l'authentification unique ?
    • Avantages du SSO
    • Inconvénients du SSO
    • Cas d'utilisation pour l'authentification unique
    • Exemples de mise en œuvre de SSO
    • 1. API (Node.js avec Express)
    • 2. Application principale (Réagir)
    • 3. Application externe (React)
  • Conclusion

Links

  • Référentiel GitHub

Vidéo de démonstration

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

Authentification unique (SSO)

Single Sign-On (SSO) est un mécanisme d'authentification qui permet aux utilisateurs de se connecter une seule fois et d'accéder à plusieurs applications ou systèmes connectés sans avoir besoin de se réauthentifier pour chacun.

SSO centralise l'authentification des utilisateurs dans un système unique et fiable (souvent appelé fournisseur d'identité ou IdP), qui gère ensuite les informations d'identification et émet des jetons ou des données de session pour vérifier l'identité de l'utilisateur sur d'autres services (appelés fournisseurs de services ou SP). ).

Comment fonctionne l'authentification unique ?

SSO fonctionne via des mécanismes sécurisés basés sur des jetons tels que OAuth 2.0, OpenID Connect (OIDC) ou Security Assertion Markup Language (SAML). Voici un flux simplifié :

  • Connexion utilisateur : l'utilisateur saisit ses informations d'identification dans le fournisseur d'identité (IdP).

  • Émission de jeton : l'IdP valide les informations d'identification et émet un jeton d'authentification (par exemple, une assertion JWT ou SAML).

  • Accès au service : le jeton est transmis aux fournisseurs de services, qui le valident et accordent l'accès sans nécessiter de connexions supplémentaires.

Avantages du SSO

  • Expérience utilisateur améliorée : les utilisateurs peuvent accéder à plusieurs services avec une seule connexion, réduisant ainsi les frictions et améliorant la convivialité.

  • Sécurité améliorée :

    • Réduit la fatigue liée aux mots de passe, qui peut conduire à des pratiques dangereuses telles que la réutilisation des mots de passe.
    • L'authentification centralisée permet des politiques de mot de passe plus strictes et l'application de l'authentification multifacteur (MFA).
  • Gestion simplifiée des utilisateurs :

    • Il est plus facile pour les administrateurs de gérer l'accès des utilisateurs aux applications connectées.
    • La révocation de l'accès à un utilisateur depuis l'IdP désactive son accès à tous les systèmes intégrés.
  • Efficacité en termes de temps et de coûts :

    • Gain de temps pour les utilisateurs et les équipes d'assistance en réduisant les demandes d'assistance liées à la connexion.
    • Réduit le temps et les coûts de développement en tirant parti des mécanismes d'authentification existants.
  • Conformité et audit :

    • L'authentification et le contrôle d'accès centralisés facilitent l'application des politiques de sécurité et le suivi de l'activité des utilisateurs.

Inconvénients du SSO

  • Point de défaillance unique :

    • Si l'IdP est indisponible ou compromis, les utilisateurs ne peuvent accéder à aucun système connecté.
    • Atténuation : utilisez des IdP redondants et assurez une haute disponibilité.
  • Mise en œuvre complexe :

    • L'intégration de SSO nécessite une planification et une expertise importantes, en particulier dans des environnements comportant des applications et des protocoles divers.
    • Atténuation : exploitez des protocoles établis comme OAuth 2.0 ou SAML et des bibliothèques SSO robustes.
  • Risques de sécurité :

    • Si un attaquant accède aux informations d'identification SSO de l'utilisateur, il peut potentiellement accéder à tous les systèmes connectés.
    • Atténuation : appliquez une MFA forte et surveillez les activités de connexion suspectes.
  • Verrouillage du fournisseur :

    • Les organisations peuvent s'appuyer fortement sur un fournisseur d'IdP spécifique, ce qui rend la migration difficile.
    • Atténuation : choisissez des normes ouvertes et évitez les solutions propriétaires.
  • Défis de la gestion des jetons :

    • Les jetons expirés ou volés peuvent perturber l'accès ou créer des failles de sécurité.
    • Atténuation : implémentez l'expiration des jetons, des mécanismes d'actualisation et un stockage sécurisé des jetons.

Cas d'utilisation de l'authentification unique

  • Applications d'entreprise :

    • Les employés peuvent accéder à divers outils et services internes avec une seule connexion.
    • Simplifie les processus d'intégration et de départ.
  • Services Cloud :

    • Les utilisateurs peuvent basculer en toute transparence entre les applications cloud sans connexions répétées.
    • Améliore la productivité et l'expérience utilisateur.
  • Portails clients :

    • Offre une expérience de connexion unifiée aux clients sur différents services.
    • Permet la personnalisation et le marketing ciblé.
  • Intégration des partenaires :

    • Facilite l'accès sécurisé aux ressources partagées entre les organisations partenaires.
    • Rationalise la collaboration et l'échange de données.

Exemples de mise en œuvre de SSO

1. API (Node.js avec Express)

L'API agit en tant que fournisseur d'identité (IdP). Il authentifie les utilisateurs et émet des jetons JWT pour l'accès.

Vous trouverez ci-dessous une ventilation structurée du code fourni, expliquant le but de chaque section pour vos abonnés. Cela constitue un exemple solide de la façon d'implémenter la fonctionnalité SSO dans la couche API.

Configuration et dépendances

Les packages suivants sont utilisés dans cette configuration :

  • express : Pour gérer les requêtes HTTP et le routage.
  • jsonwebtoken : pour générer et vérifier des JWT.
  • cors : pour gérer les demandes d'origine croisée provenant de différentes applications clientes.
  • @faker-js/faker : Pour générer des données d'utilisateur fictif et de tâches.
  • cookie-parser : pour analyser les cookies envoyés dans les requêtes.
  • dotenv : Pour charger les variables d'environnement en toute sécurité.
Configuration
  • dotenv est utilisé pour gérer la clé secrète en toute sécurité.
  • Un secret de secours est fourni pour les environnements de développement.
dotenv.config();
const SECRET_KEY = process.env.SECRET_KEY || "secret";
Copier après la connexion
Copier après la connexion
Intergiciel
  • CORS garantit que les requêtes provenant d'origines frontales spécifiques (application principale et externe) sont autorisées.
  • cookieParser analyse les cookies envoyés par les clients.
  • express.json permet d'analyser les corps des requêtes JSON.
app.use(
  cors({
    origin: ["http://localhost:5173", "http://localhost:5174"],
    credentials: true,
  })
);
app.use(express.json());
app.use(cookieParser());
Copier après la connexion
Copier après la connexion

Authentification des utilisateurs et génération de jetons

Les données simulées simulent les utilisateurs et leurs tâches associées.

Les utilisateurs ont des rôles (administrateur ou utilisateur) et des informations de profil de base.
Les tâches sont liées aux identifiants des utilisateurs pour un accès personnalisé.

  • /login : authentifie les utilisateurs en fonction de leur e-mail et de leur mot de passe.

Les utilisateurs reçoivent un cookie (sso_token) contenant le JWT lors d'une connexion réussie.
Ce jeton est sécurisé, HTTP uniquement et limité dans le temps pour éviter toute falsification.

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" });
  }
});
Copier après la connexion
Copier après la connexion
  • /verify : valide l’identité de l’utilisateur en décodant le jeton. Les jetons invalides entraînent une réponse non autorisée.
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" });
  }
});
Copier après la connexion
Copier après la connexion
  • /logout : efface le cookie contenant le jeton JWT.

Garantit que les utilisateurs peuvent se déconnecter en toute sécurité en effaçant leur jeton.

dotenv.config();
const SECRET_KEY = process.env.SECRET_KEY || "secret";
Copier après la connexion
Copier après la connexion
  • /todos : récupère les tâches associées à l'utilisateur authentifié.
app.use(
  cors({
    origin: ["http://localhost:5173", "http://localhost:5174"],
    credentials: true,
  })
);
app.use(express.json());
app.use(cookieParser());
Copier après la connexion
Copier après la connexion
  • /todos : ajoute une nouvelle tâche pour l'utilisateur authentifié.
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" });
  }
});
Copier après la connexion
Copier après la connexion
  • /todos/:id : met à jour une tâche en fonction de l'ID fourni.
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" });
  }
});
Copier après la connexion
Copier après la connexion
  • /todos/:id : supprime une tâche en fonction de l'ID fourni.
app.post("/logout", (req, res) => {
  res.clearCookie("sso_token");
  res.json({ message: "Logout successful" });
});
Copier après la connexion

2. Application principale (Réagir)

L'application principale agit en tant que fournisseur de services (SP) qui consomme l'API et gère les interactions des utilisateurs.

Vous trouverez ci-dessous une ventilation structurée du code fourni, expliquant le but de chaque section pour vos abonnés. Cela constitue un exemple solide de la façon d'implémenter la fonctionnalité SSO dans la couche d'application principale.

  • Composant d'application

Le composant App gère l'authentification des utilisateurs et les redirections en fonction de l'état de connexion.

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);
});
Copier après la connexion
  • Composant de connexion

Le composant de connexion gère la connexion de l'utilisateur et redirige vers la page Todos une fois l'authentification réussie.

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 });
});
Copier après la connexion
  • Composant Todos

Le composant Todos affiche les tâches spécifiques à l'utilisateur et permet d'ajouter et de supprimer des tâches.

// 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" });
  }
});
Copier après la connexion

3. Application externe (Réagir)

L'application externe agit comme un autre fournisseur de services (SP) qui consomme l'API et gère les interactions des utilisateurs.

Vous trouverez ci-dessous une ventilation structurée du code fourni, expliquant le but de chaque section pour vos abonnés. Cela constitue un exemple solide de la façon d'implémenter la fonctionnalité SSO dans la couche d'application externe.

  • Composant d'application

Le composant App gère l'authentification des utilisateurs et les redirections en fonction de l'état de connexion.

// 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" });
  }
});
Copier après la connexion
  • Composant Todos

Le composant Todos affiche les tâches spécifiques à l'utilisateur.

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;
Copier après la connexion

Conclusion

L'authentification unique (SSO) simplifie l'authentification des utilisateurs et la gestion des accès sur plusieurs applications, améliorant ainsi l'expérience utilisateur, la sécurité et l'efficacité opérationnelle. En centralisant l'authentification et en tirant parti de mécanismes sécurisés basés sur des jetons, les organisations peuvent rationaliser l'accès des utilisateurs, réduire les risques liés aux mots de passe et améliorer les capacités de conformité et d'audit.

Bien que le SSO offre de nombreux avantages, il présente également des défis tels que des points de défaillance uniques, des exigences de mise en œuvre complexes, des risques de sécurité et une dépendance potentielle envers un fournisseur. Les organisations doivent soigneusement planifier et mettre en œuvre des solutions SSO pour atténuer ces risques et maximiser les avantages de l'authentification centralisée.

En suivant les meilleures pratiques, en tirant parti des protocoles établis et en choisissant des normes ouvertes, les organisations peuvent mettre en œuvre avec succès le SSO pour améliorer l'expérience utilisateur, la sécurité et l'efficacité opérationnelle dans leurs applications et systèmes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal