シングル サインオン (SSO) は、ユーザーが一度ログインすると、接続されている複数のアプリケーションやシステムにそれぞれ再認証することなくアクセスできるようにする認証メカニズムです。 SSO は、ユーザー認証を単一の信頼できるシステム (アイデンティティ プロバイダー (IdP) と呼ばれることが多い) に集中させ、そのシステムが資格情報を管理し、トークンまたはセッション データを発行して、他のサービス (サービス プロバイダー (SP) と呼ばれる) 間でユーザーの ID を検証します。
このガイドでは、SSO の仕組み、その利点と欠点、一般的な使用例、API (Express を使用した Node.js)、メイン アプリケーション (React)、および外部アプリケーションでの SSO 実装の例について説明します。アプリケーション(React)。 SSO の原則と実践を理解することで、組織はアプリケーションとシステム全体のユーザー エクスペリエンス、セキュリティ、運用効率を向上させることができます。
シングル サインオン (SSO) は、ユーザーが一度ログインすると、接続されている複数のアプリケーションやシステムにそれぞれ再認証することなくアクセスできるようにする認証メカニズムです。
SSO は、ユーザー認証を単一の信頼できるシステム (アイデンティティ プロバイダー (IdP) と呼ばれることが多い) に集中させ、そのシステムが認証情報を管理し、トークンまたはセッション データを発行して、他のサービス (サービス プロバイダー (SP) と呼ばれる) 全体でユーザーの ID を検証します。 ).
SSO は、OAuth 2.0、OpenID Connect (OIDC)、または Security Assertion Markup Language (SAML) などの安全なトークンベースのメカニズムを通じて動作します。簡略化されたフローは次のとおりです:
ユーザー ログイン: ユーザーはアイデンティティ プロバイダー (IdP) に資格情報を入力します。
トークン発行: IdP は資格情報を検証し、認証トークン (JWT または SAML アサーションなど) を発行します。
サービス アクセス: トークンはサービス プロバイダーに渡され、サービス プロバイダーがそれを検証し、追加のログインを必要とせずにアクセスを許可します。
ユーザー エクスペリエンスの強化: ユーザーは 1 回のログインで複数のサービスにアクセスできるため、煩雑さが軽減され、使いやすさが向上します。
セキュリティの向上:
簡素化されたユーザー管理:
時間とコストの効率:
コンプライアンスと監査:
単一障害点:
複雑な実装:
セキュリティリスク:
ベンダーロックイン:
トークン管理の課題:
エンタープライズ アプリケーション:
クラウド サービス:
カスタマーポータル:
パートナー統合:
API はアイデンティティ プロバイダー (IdP) として機能します。ユーザーを認証し、アクセス用の JWT トークンを発行します。
以下は、提供されたコードの構造化された内訳であり、フォロワー向けに各セクションの目的を説明しています。これは、API レイヤーに SSO 機能を実装する方法の確実な例として機能します。
このセットアップでは次のパッケージが使用されます:
dotenv.config(); const SECRET_KEY = process.env.SECRET_KEY || "secret";
app.use( cors({ origin: ["http://localhost:5173", "http://localhost:5174"], credentials: true, }) ); app.use(express.json()); app.use(cookieParser());
モック データは、ユーザーとユーザーに関連付けられた ToDo をシミュレートします。
ユーザーにはロール (管理者またはユーザー) と基本的なプロフィール情報があります。
Todo はユーザー ID にリンクされており、パーソナライズされたアクセスが可能です。
ユーザーはログインに成功すると、JWT を含む Cookie (sso_token) を受け取ります。
このトークンは安全で、HTTP 専用であり、改ざんを防ぐために期間が制限されています。
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" }); } });
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" }); } });
トークンをクリアすることで、ユーザーが安全にログアウトできるようにします。
dotenv.config(); const SECRET_KEY = process.env.SECRET_KEY || "secret";
app.use( cors({ origin: ["http://localhost:5173", "http://localhost:5174"], credentials: true, }) ); app.use(express.json()); app.use(cookieParser());
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" }); } });
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" }); } });
app.post("/logout", (req, res) => { res.clearCookie("sso_token"); res.json({ message: "Logout successful" }); });
メイン アプリケーションは、API を使用してユーザー インタラクションを管理するサービス プロバイダー (SP) として機能します。
以下は、提供されたコードの構造化された内訳であり、フォロワー向けに各セクションの目的を説明しています。これは、メイン アプリケーション層に SSO 機能を実装する方法の確実な例として機能します。
アプリ コンポーネントはユーザー認証を管理し、ログイン ステータスに基づいてリダイレクトします。
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); });
ログイン コンポーネントはユーザーのログインを処理し、認証が成功すると Todos ページにリダイレクトします。
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 }); });
Todos コンポーネントはユーザー固有の Todo を表示し、Todo の追加と削除を可能にします。
// 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" }); } });
外部アプリケーションは、API を使用してユーザー操作を管理する別のサービス プロバイダー (SP) として機能します。
以下は、提供されたコードの構造化された内訳であり、フォロワー向けに各セクションの目的を説明しています。これは、外部アプリケーション層に SSO 機能を実装する方法の確実な例として機能します。
アプリ コンポーネントはユーザー認証を管理し、ログイン ステータスに基づいてリダイレクトします。
// 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" }); } });
Todos コンポーネントには、ユーザー固有の Todo が表示されます。
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;
シングル サインオン (SSO) は、複数のアプリケーションにわたるユーザー認証とアクセス管理を簡素化し、ユーザー エクスペリエンス、セキュリティ、運用効率を向上させます。認証を一元化し、安全なトークンベースのメカニズムを活用することで、組織はユーザー アクセスを合理化し、パスワード関連のリスクを軽減し、コンプライアンスと監査機能を向上させることができます。
SSO には多くの利点がありますが、単一障害点、複雑な実装要件、セキュリティ リスク、潜在的なベンダー ロックインなどの課題も存在します。組織は、これらのリスクを軽減し、集中認証の利点を最大化するために、SSO ソリューションを慎重に計画して実装する必要があります。
ベスト プラクティスに従い、確立されたプロトコルを活用し、オープン スタンダードを選択することで、組織は SSO を適切に実装して、アプリケーションとシステム全体のユーザー エクスペリエンス、セキュリティ、運用効率を向上させることができます。
以上がシングル サインオン (SSO): React と ExpressJS の包括的なガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。