单点登录sso

326 阅读7分钟

1.Session+cookie模式

(1)前端单点登录(简称SSO)的Session+Cookie模式实现思路主要涉及到以下几个关键步骤:

  1. 认证中心(Auth Server)的设计

    • 认证中心负责用户的登录认证。用户在这里输入用户名和密码,如果验证通过,认证中心会生成一个Session,并将Session ID返回给前端。
    • 通常,这个Session ID会通过Cookie的方式发送到前端,并保存在浏览器的本地。
    • 同一个父域名下的子域名可以共享浏览器中的cookie。比如在父域名的浏览器中(认证中心)设置cookie,在子域名的浏览器中(子系统A,子系统B)也可以拿到这个域名。
  2. Cookie的传递

    • 当用户登录成功后,认证中心会设置一个Cookie,该Cookie通常包含Session ID,并且设置为HttpOnly和Secure(防止XSS和中间人攻击)。
    • 用户之后的请求都会带上这个Cookie,作为身份验证的凭据。
  3. 服务器的验证

    • 当用户访问服务器的资源时,服务器会检查请求中是否包含有效的Cookie。
    • 如果包含Cookie,服务提供方会向认证中心发起请求,验证这个Session ID是否有效。
    • 认证中心验证Session ID后,返回验证结果给服务提供方。如果Session ID有效,服务提供方会允许用户访问资源;否则,拒绝访问。
  4. Session的管理

    • 认证中心需要维护一个Session的存储,通常是基于数据库或缓存系统(如Redis)。
    • Session需要有一个合理的过期时间,当Session过期后,用户需要重新登录。
    • 还需要考虑Session的安全性问题,如防止Session劫持等。
  5. 跨域问题

    • 在实现单点登录时,可能会遇到跨域问题。可以通过设置CORS(跨源资源共享)策略来解决。
    • 认证中心和服务器需要配置正确的CORS策略,允许跨域请求。
  6. 安全性考虑

    • 使用HTTPS协议来传输数据,确保数据的机密性和完整性。
    • 对敏感操作进行二次验证,如发送验证码到用户的注册手机或邮箱。
    • 定期更换密钥和加密算法,提高系统的安全性。
  7. 前端实现

    • 前端在接收到认证中心的登录响应后,需要保存Cookie,并在之后的请求中自动带上这个Cookie。
    • 可以使用浏览器的内置API(如document.cookie)来操作Cookie。
    • 对于跨域请求,可以使用withCredentials属性来确保Cookie被正确发送。
  8. withCredentials 怎么使用

withCredentials 是一个 XMLHttpRequest 或者 Fetch API 的选项,它用于控制跨域请求时是否携带认证信息(如 cookies、HTTP 认证及客户端 SSL 证明等)。默认情况下,跨域请求不会发送任何 cookies。但如果你设置了 withCredentials 为 true,浏览器就会将 cookies 包含在跨域请求中,前提是服务器也允许这种跨域请求(即设置了正确的 CORS 响应头)。

(1)XMLHttpRequest 示例

var xhr = new XMLHttpRequest();  
xhr.withCredentials = true; // 允许携带跨域 cookies  
  
xhr.open('GET', 'https://example.com/api/data', true);  
xhr.onreadystatechange = function() {  
  if (xhr.readyState == 4 && xhr.status == 200) {  
    // 请求成功,处理响应  
    console.log(xhr.responseText);  
  }  
};  
xhr.send();

(2)Fetch API 示例

Fetch API 是现代 JavaScript 中用于发起网络请求的新方法,它也支持 credentials 选项,其值可以是 omit(默认值,不发送 cookies)、same-origin(只发送同源请求的 cookies)或 include(无论是否跨域都发送 cookies)。

fetch('https://example.com/api/data', {  
  credentials: 'include', // 允许携带跨域 cookies  
  method: 'GET'  
})  
.then(response => response.json())  
.then(data => {  
  // 请求成功,处理数据  
  console.log(data);  
})  
.catch(error => {  
  // 处理错误  
  console.error('Fetch error:', error);  
});

(3)服务器端的 CORS 配置

为了让跨域请求携带 cookies,服务器端也需要配合设置 CORS 相关的响应头。服务器需要在响应头中包括 Access-Control-Allow-Origin,并且其值不能是 *,而应该是请求的来源地址,或者是一个允许跨域请求的域名列表。此外,还需要包含 Access-Control-Allow-Credentials: true 来表明服务器允许携带认证信息。

例如,一个设置 CORS 的 Node.js Express 服务器端示例:

const express = require('express');  
const cors = require('cors');  
const app = express();  
  
// 设置 CORS 中间件,允许携带认证信息  
const corsOptions = {  
  origin: 'http://your-frontend-origin.com', // 或者使用函数动态判断 origin  
  credentials: true, // 允许跨域请求携带认证信息  
  // 可以添加其他 CORS 配置项...  
};  
  
app.use(cors(corsOptions));  
  
// 其他路由和中间件...  
  
app.listen(3000, () => {  
  console.log('Server is running on port 3000');  
});

请注意,出于安全考虑,只有当你完全信任你正在与之交互的服务器时,才应启用跨域 cookies 的发送。因为一旦启用了 withCredentials,你的应用就会容易受到 CSRF(跨站请求伪造)攻击,所以务必确保你已经实施了适当的安全措施。

(2)该模式的优点:

认证中心有很强的控制能力,可以让用户在多个系统同时退出。只要认证中心把Session表格的用户信息清掉。用户下次访问时,系统再拿sid去认证中心验证,发现sid失效了,子系统就处于为登录状态。

(3)该模式的劣势:

如果大量用户访问,会造成多个子系统向认证中心验证sid,造成服务器压力大。并且如果认证中心挂了,所有的子系统都无法登录。如果子系统扩容,认证中心也要跟着扩容,造成资源的浪费。

2.Token+Refresh Token模式

单点登录(Single Sign-On,简称SSO)的Token模式是一种实现分布式系统中用户认证的方式。在这种模式下,用户只需要在一个系统中登录一次,就可以访问所有相互信任的应用系统而不需要再次登录。以下是Token模式在单点登录中的实现思路:

  1. 用户登录

    • 用户选择一个应用系统进行登录,通常是通过输入用户名和密码。
    • 该应用系统验证用户的登录信息,如果验证通过,它将生成一个Token。
  2. 生成Token

    • Token是一个包含了用户身份信息的字符串,通常是由服务端按照一定的规则生成的。
    • Token中可能包含用户ID、角色、权限等必要信息,并且通常会被加密或签名以保证安全性。
    • Token的生成和使用一般基于JWT(JSON Web Tokens)标准,这是一种开放标准(RFC 7519)定义的方式,用于在双方之间安全地传输信息。这些信息可以被验证和信任,因为它们是数字签名的。
  3. Token传递

    • 一旦Token生成,它会被返回给客户端(通常是浏览器)。
    • 客户端在后续的请求中会将Token附加在请求头(如Authorization字段)中发送给服务端。
  4. Token验证

    • 当用户尝试访问其他应用系统时,这些系统会检查请求中是否包含有效的Token。
    • 服务端会验证Token的有效性,包括检查Token是否过期、是否被篡改以及是否属于已认证的用户。
    • 如果Token有效,则用户无需再次登录即可访问该系统。
  5. Token刷新

    • 为了处理Token过期的情况,可能会使用一种称为Refresh Token的机制。
    • 当用户的访问Token过期时,可以使用Refresh Token来获取一个新的访问Token,而无需用户重新登录。
    • Refresh Token通常具有更长的有效期,并且需要更加严格地保护。
  6. 安全性考虑

    • Token的传输应该使用HTTPS来确保安全性,防止Token在传输过程中被截获。
    • Token的存储也应该谨慎处理,避免在客户端以明文形式存储,防止XSS攻击。
    • 服务端需要妥善保管用于签名Token的密钥,防止密钥泄露。
  7. Token失效与撤销

    • 当用户注销或管理员需要撤销用户的访问权限时,需要有机制使Token失效。
    • 这通常可以通过在服务端维护一个Token的失效列表或使用黑名单机制来实现。

Token模式的优点在于它的灵活性和可扩展性,因为每个应用系统都可以独立验证Token的有效性,而无需与认证中心进行实时通信。然而,这也带来了额外的复杂性,特别是在处理Token的生成、存储、传输和验证等方面。同时,还需要考虑Token的安全性、有效期管理以及失效机制等问题。

token失效的情况,拿refresh token换取新的token。