本文罗列常见的单点登录(SSO)解决方案,然后通过一个express示例展示如何通过第三方服务实现单点登录功能,欢迎各位大佬指点。
-
OAuth 2.0: 一种广泛使用的授权框架,允许应用程序在HTTP服务上获取对用户账户的有限访问权限。它通常用于社交登录场景(如使用谷歌、Facebook或推特登录)的SSO。
-
SAML(安全断言标记语言): 一种在各方(特别是身份提供者和服务提供者之间)交换认证和授权数据的开放标准。
-
OpenID Connect: 在OAuth 2.0协议之上的一个简单身份层,允许客户端验证最终用户的身份并获取基本的个人资料信息。
-
JWT(JSON Web Tokens): 一种紧凑且URL安全的表示方式,用于在两方之间传递声明。在SSO中非常有用,因为它可以通过URL、POST参数或HTTP头内部轻松传输。
-
LDAP(轻量级目录访问协议): 在企业环境中常用,允许从目录服务(如Active Directory)进行集中式认证。
-
自定义SSO解决方案: 一些组织根据自己的特定需求构建定制的SSO解决方案,通常与他们的内部用户管理系统集成。
1. SSO提供商的工作原理
-
首次与SSO提供商建立连接: 用户首次登录使用SSO提供商的应用程序时,浏览器连接到SSO提供商,用户进行身份验证(例如,输入用户名和密码)。
-
SSO提供商设置Cookie或会话: 认证成功后,SSO提供商为用户创建一个会话,并通常在用户的浏览器中设置一个Cookie。这个Cookie包含表示已认证会话的令牌或标识符。
-
首次建立SSO: 这种初始认证和会话创建建立了首个单点登录(SSO)。用户登录的应用程序现在可以与SSO提供商通信,确认用户身份并接收访问令牌或类似凭据来访问用户信息。
-
后续应用程序利用SSO: 用户访问与同一SSO提供商集成的另一个应用程序时,这个应用程序也将用户重定向到SSO提供商进行认证。
-
SSO提供商识别现有会话: SSO提供商通过用户浏览器中的Cookie检测到现有会话。如果会话有效,它识别用户已经被认证。
-
在多个应用程序中建立SSO: 无需用户再次登录,SSO提供商就通知第二个应用程序用户的认证状态。然后第二个应用程序授予用户访问权限,有效地将SSO扩展到这个应用程序。
-
无缝的用户体验: 用户在不同应用程序之间无需重复登录即可体验到无缝切换。这是因为SSO提供商集中管理了认证过程。
总结
总的来说,SSO过程确实围绕着SSO提供商的集中认证,然后扩展到其他应用程序。浏览器与SSO提供商的交互,特别是通过Cookie或会话令牌,是维护和识别用户在多个应用程序中的认证状态的关键。
此过程的简单示意图

2. 如何实现单点登录(SSO)
SSO允许用户一次认证后即可访问多个应用程序,无需每个应用都重新登录。以下是在使用OAuth的Web应用程序中实现SSO的基本概述:
-
用户尝试访问您的应用程序
- 用户浏览您的Web应用程序并尝试访问需要认证的受保护资源。
-
重定向到SSO提供商(OAuth提供商)
- 您的应用程序将用户重定向到SSO提供商(本例中的OAuth提供商)的登录页面。这通常通过像
./login这样的路由完成。 - 然后要求用户登录到SSO提供商(除非他们已经登录)。这可能是谷歌、Facebook等服务的登录页面。
- 您的应用程序将用户重定向到SSO提供商(本例中的OAuth提供商)的登录页面。这通常通过像
-
用户在SSO提供商处认证
- 用户登录到SSO提供商。这次登录完全由SSO提供商管理,您的应用程序不会看到用户的凭据。
-
带有授权码的重定向回到您的应用程序
- 认证成功后,SSO提供商将用户连同授权码一起重定向回您的应用程序(到
redirect_uri)。
- 认证成功后,SSO提供商将用户连同授权码一起重定向回您的应用程序(到
-
您的应用程序请求访问令牌
- 您的应用程序使用此授权码向SSO提供商请求访问令牌,正如在OAuth流程中描述的那样。
-
您的应用程序建立会话
- 一旦您的应用程序收到访问令牌,就可以为用户创建一个会话。这个会话表明用户已登录到您的应用程序。
- 会话可以通过各种方法建立,例如设置Cookie或使用服务器端会话存储。
-
多个应用程序的SSO
- 这就是SSO的关键所在:如果用户现在导航到另一个也使用相同SSO提供商进行认证的应用程序,他们将无需再次登录。
- 当用户尝试访问第二个应用程序时,它也会将他们重定向到SSO提供商。由于用户已经在SSO提供商处进行了认证,他们会立即被重定向回第二个应用程序,并附上一个新的授权码。
- 第二个应用程序然后遵循相同的过程为用户建立自己的会话。
-
统一注销(可选)
- 一个完整的SSO实现通常包括统一注销机制。当用户从一个应用程序注销时,它可以触发一个注销过程,这也将用户从SSO提供商和可能的其他连接应用程序注销。
总结
在使用OAuth的SSO实现中,关键在于用户的认证由一个中心服务(OAuth提供商)管理,个别应用程序信任这个服务正确地对用户进行认证。一旦在OAuth提供商处认证,用户就可以无缝访问多个应用程序,无需重新输入凭据。
您的示例代码演示了这一过程的初始部分,其中用户被重定向到OAuth提供商进行认证,然后收到一个用于交换访问令牌的授权码。这是构建支持SSO的应用程序的基础步骤。
3. JavaScript代码示例:OAuth 2.0 + JWT
创建一个简单的SSO客户端示例。此示例将模拟使用OAuth与第三方服务(如谷歌)进行SSO登录。请注意,在实际情况中,您需要与提供商建立OAuth客户端并处理服务器端令牌验证。
javascript
const express = require('express');
const axios = require('axios');
const app = express();
const PORT = 3000;
// 使用您的客户端凭证替换这些
const CLIENT_ID = 'YOUR_CLIENT_ID';
const CLIENT_SECRET = 'YOUR_CLIENT_SECRET';
app.get('/login', (req, res) => {
// 重定向到OAuth提供商的登录页面
const authUrl = `https://oauthprovider.com/auth?response_type=code&client_id=${CLIENT_ID}&redirect_uri=http://localhost:3000/callback`;
res.redirect(authUrl);
});
app.get('/callback', async (req, res) => {
const authCode = req.query.code;
// 用授权码换取访问令牌
try {
const response = await axios.post('https://oauthprovider.com/token', {
code: authCode,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
redirect_uri: 'http://localhost:3000/callback',
grant_type: 'authorization_code'
});
const accessToken = response.data.access_token;
// 使用访问令牌访问受保护的资源
res.send(`已使用访问令牌登录: ${accessToken}`);
} catch (error) {
res.send('认证过程中出错');
}
});
app.listen(PORT, () => {
console.log(`服务器运行在端口 ${PORT}`);
});
解释:OAuth授权码流程逐步分析
-
用户启动登录
- 用户在您的应用程序上点击"使用[OAuth提供商]登录"。
-
应用程序重定向到OAuth提供商
- 您的应用程序将用户重定向到OAuth提供商的授权URL。
- 此URL包括:
client_id:您的应用程序的唯一标识符,当您在OAuth提供商注册您的应用程序时提供。redirect_uri:OAuth提供商在授权后将用户发送到的URL。这必须在OAuth提供商处注册。scope:您的应用程序请求访问用户账户的权限级别。response_type:设置为code,表明您的应用程序期望获得授权码。
-
用户在OAuth提供商处认证并授权
- OAuth提供商向用户展示登录提示(除非他们已经登录)。
- 用户被要求授权您的应用程序访问他们的信息或代表他们执行操作。
-
OAuth提供商发出授权码
- 用户登录并授权后,OAuth提供商将他们重定向回您的应用程序指定的
redirect_uri。 - 重定向URL包括作为查询参数的授权码,例如,
https://yourapp.com/callback?code=AUTH_CODE_HERE。
- 用户登录并授权后,OAuth提供商将他们重定向回您的应用程序指定的
-
应用程序接收授权码
- 您的应用程序在
redirect_uri端点接收到这个请求。 - 然后从查询参数中提取
authCode。
- 您的应用程序在
-
应用程序请求访问令牌
- 您的应用程序向OAuth提供商的令牌端点发出服务器到服务器的请求。
- 此请求包括:
- 收到的
authCode。 - 您的应用程序的
client_id和client_secret(在应用程序注册期间获得的秘密密钥,用于认证您的应用程序)。 redirect_uri(用于验证)。
- 收到的
- 目的是用
authCode换取访问令牌。
-
OAuth提供商验证并响应
-
OAuth提供商验证请求,确保
authCode、client_id、client_secret和redirect_uri都是有效的。 -
验证通过后,OAuth提供商响应一个访问令牌。
-
-
接收访问令牌
- 您的应用程序接收到访问令牌。
- 此令牌用于代表用户向OAuth提供商的API发出认证请求。
总结
在此过程中,authCode作为OAuth提供商提供的一次性凭证。它是确保登录的用户是授权用户的一部分,并用于安全地交换访问令牌,而不会暴露用户凭据。访问令牌是允许您的应用程序以安全方式访问用户数据的关键。
English version: Common Single Sign-On (SSO) Solutions With A Demo
-
OAuth 2.0: A widely-used authorization framework that enables applications to obtain limited access to user accounts on an HTTP service. It's commonly used for SSO in social login scenarios (like signing in with Google, Facebook, or Twitter).
-
SAML (Security Assertion Markup Language): An open standard for exchanging authentication and authorization data between parties, particularly between an identity provider and a service provider.
-
OpenID Connect: A simple identity layer on top of the OAuth 2.0 protocol, allowing clients to verify the identity of the end-user and to obtain basic profile information.
-
JWT (JSON Web Tokens): A compact, URL-safe means of representing claims to be transferred between two parties. It's useful in SSO as it can be easily transmitted through a URL, POST parameter, or inside an HTTP header.
-
LDAP (Lightweight Directory Access Protocol): Commonly used in enterprise environments, it allows centralized authentication from a directory service (like Active Directory).
-
Custom SSO solutions: Some organizations build custom SSO solutions tailored to their specific needs, often integrating with their internal user management systems.
1. How A SSO Provider Works
-
Initial Connection with SSO Provider: The process begins when a user first logs in to an application that uses an SSO provider. The browser connects to the SSO provider, and the user authenticates themselves (e.g., by entering a username and password).
-
SSO Provider Sets a Cookie or Session: After successful authentication, the SSO provider creates a session for the user and typically sets a cookie in the user's browser. This cookie contains a token or identifier representing the authenticated session.
-
First SSO Establishment: This initial authentication and session creation establish the first Single Sign-On (SSO). The application that the user logged into can now communicate with the SSO provider to confirm the user's identity and receive an access token or similar credentials to access the user's information.
-
Subsequent Applications Leverage SSO: When the user then accesses another application integrated with the same SSO provider, this application also redirects the user to the SSO provider for authentication.
-
SSO Provider Recognizes Existing Session: The SSO provider detects the existing session through the cookie in the user's browser. If the session is valid, it recognizes the user as already authenticated.
-
SSO Established Across Multiple Applications: Without requiring the user to log in again, the SSO provider informs the second application of the user's authenticated state. The second application then grants access to the user, effectively extending the SSO to this application as well.
-
Seamless User Experience: The user experiences a seamless transition between applications without the need for repeated logins. This is because the SSO provider centralizes and manages the authentication process.
Summary
In summary, the SSO process indeed revolves around a central authentication by the SSO provider, which then extends to other applications. The browser's interaction with the SSO provider, particularly through cookies or session tokens, is key to maintaining and recognizing the user's authenticated state across multiple applications.
A Simple Diagram to Show This Process

2. How Single Sign-On (SSO) is Implemented
SSO allows a user to authenticate once and gain access to multiple applications without having to log in again for each app. Here's a basic outline of how SSO might be implemented in a web application using OAuth:
- User Attempts to Access Your Application
- The user navigates to your web application and attempts to access a protected resource that requires authentication.
- Redirection to the SSO Provider (OAuth Provider)
- Instead of presenting a traditional login screen, your application redirects the user to an SSO provider (the OAuth provider in this case). This is typically done via a route like
./login. - The user is then asked to log in to the SSO provider (unless they are already logged in). This could be a login page for a service like Google, Facebook, etc.
- User Authenticates with the SSO Provider
- The user logs in to the SSO provider. This login is managed entirely by the SSO provider, and your application doesn't see the user's credentials.
- Redirection Back to Your Application with an Auth Code
- After successful authentication, the SSO provider redirects the user back to your application (to the
redirect_uri), including an authorization code.
- Your Application Requests an Access Token
- Your application uses this authorization code to request an access token from the SSO provider, as described in the OAuth flow.
- Your Application Establishes a Session
- Once your application receives the access token, it can create a session for the user. This session indicates that the user is logged in to your application.
- The session could be established using various methods, such as setting a cookie or using server-side session storage.
- SSO for Multiple Applications
- Here's where the SSO aspect comes in: If the user now navigates to another application that also uses the same SSO provider for authentication, they won't need to log in again.
- When the user attempts to access the second application, it also redirects them to the SSO provider. Since the user is already authenticated with the SSO provider, they are immediately redirected back to the second application with a new authorization code.
- The second application then follows the same process to establish its own session for the user.
- Unified Logout (Optional)
- A complete SSO implementation often includes a unified logout mechanism. When the user logs out from one application, it can trigger a logout process that also logs the user out of the SSO provider, and potentially other connected applications.
Summary
In an SSO implementation using OAuth, the key is that the user's authentication is managed by a central service (the OAuth provider), and individual applications trust this service to correctly authenticate users. Once authenticated with the OAuth provider, the user can seamlessly access multiple applications without needing to re-enter credentials.
Your sample code demonstrates the initial part of this process, where a user is redirected to an OAuth provider for authentication and then receives an authorization code that is exchanged for an access token. This is the foundational step in building an SSO-enabled application.
3. JavaScript Code Example for SSO Demonstration
Let's create a simple demonstration of an SSO client. This example will simulate an SSO login using OAuth with a third-party service (like Google). Note that in a real-world scenario, you would need to set up an OAuth client with the provider and handle server-side token validation.
javascript
const express = require('express');
const axios = require('axios');
const app = express();
const PORT = 3000;
// Replace these with your client credentials
const CLIENT_ID = 'YOUR_CLIENT_ID';
const CLIENT_SECRET = 'YOUR_CLIENT_SECRET';
app.get('/login', (req, res) => {
// Redirect to the OAuth provider's login page
const authUrl = `https://oauthprovider.com/auth?response_type=code&client_id=${CLIENT_ID}&redirect_uri=http://localhost:3000/callback`;
res.redirect(authUrl);
});
app.get('/callback', async (req, res) => {
const authCode = req.query.code;
// Exchange auth code for access token
try {
const response = await axios.post('https://oauthprovider.com/token', {
code: authCode,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
redirect_uri: 'http://localhost:3000/callback',
grant_type: 'authorization_code'
});
const accessToken = response.data.access_token;
// Use the access token to access protected resources
res.send(`Logged in with access token: ${accessToken}`);
} catch (error) {
res.send('Error during authentication');
}
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Explaination: Step-by-Step OAuth Authorization Code Flow
- User Initiates Login
- The user clicks "Login with [OAuth Provider]" on your application.
- Application Redirects to OAuth Provider
- Your application redirects the user to the OAuth provider's authorization URL.
- This URL includes:
client_id: A unique identifier for your application, provided by the OAuth provider when you register your app.redirect_uri: The URL to which the OAuth provider will send the user after authorization. This must be registered with the OAuth provider.scope: The level of access your application is requesting from the user's account.response_type: Set tocode, indicating that your application expects an authorization code.
- User Authenticates and Authorizes
- The user is presented with a login prompt by the OAuth provider (unless they are already logged in).
- The user is asked to authorize your application to access their information or perform actions on their behalf.
- OAuth Provider Issues Authorization Code
- After the user logs in and grants permission, the OAuth provider redirects them back to the
redirect_urispecified by your application. - The redirection URL includes an authorization code as a query parameter, e.g.,
https://yourapp.com/callback?code=AUTH_CODE_HERE.
- Application Receives Authorization Code
- Your application receives this request at the
redirect_uriendpoint. - It then extracts the
authCodefrom the query parameters.
- Application Requests Access Token
- Your application makes a server-to-server request to the OAuth provider's token endpoint.
- This request includes:
- The
authCodereceived. - Your application's
client_idandclient_secret(a secret key obtained during app registration, used to authenticate your application). - The
redirect_uri(for verification).
- The
- The purpose is to exchange the
authCodefor an access token.
- OAuth Provider Validates and Responds
- The OAuth provider validates the request, ensuring that the
authCode,client_id,client_secret, andredirect_uriare all valid. - Once validated, the OAuth provider responds with an access token.
- Access Token Received
- Your application receives the access token.
- This token is used to make authenticated requests to the OAuth provider's API on behalf of the user.
Summary
In this process, the authCode serves as a one-time-use credential provided by the OAuth provider. It's a part of ensuring that the user logging in is the one who granted permission, and it's used to securely exchange for an access token without exposing user credentials. The access token is the key that allows your application to access the user's data in a secure manner.