目录
一、Cookie+Session登录
三、单点登录(Single Sign On——一次登录,全线通用)
四、Oauth2.0
一、Cookie+Session登录
HTTP是一种无状态的协议,客户端每次发送请求时,首先要和服务端创建一个连接,在请求完成之后会断开这个连接。
这种方式能够节省传输时占用的连接资源,但同时也存在一个问题:每次请求都是独立的,服务器没法判断本次请求和上一次请求是否来自同一个用户,进而也没法判断用户的登录状态。
为了解决HTTP无状态的问题,Lou等在1994年的时候,推出了Cookie
。
Cookie是服务端发送给客户端的一段特殊信息,这些信息以文本的方式存放在客户端,客户端每次向服务端发送请求时都会带上这些特殊信息。
有了Cookie之后,服务端就可以获取到客户端传递过来的信息,若是需要对信息进行验证,还需要经过Session
。
客户端请求服务端,服务端会为此次请求开辟一块内存区域,这就是Session对象。
有了Cookie+Session之后,我们就能够进行登录认证了。
1. Cookie+Session实现流程
Cookie+Session的登录方式是最经典的一种登录方式,如今仍有大量企业在用。
用户首次登录时:
先访问a.com/login,输入账号密码登录。
服务器验证密码无误后,会建立SessionId,并将它保存起来。
服务端响应这个HTTP请求,并经过Set-Cookie头信息,将SessionId写入Cookie中。
浏览器会根据Set-Cookie中的信息,自动将SessionId存储在cookie中。
服务端的SessionId可能存放在不少地方,如内存、文件、数据库等。
第一次登录完成之后,后续的访问就能够直接使用Cookie进行身份验证了:
用户访问a.com/page页面时,会自动带上第一次登录时写入的Cookie。
服务端对比Cookie中的SessionId和保存在服务端的SessionId是否一致。
若是一致,则身份验证成功。
2. Cookie+Session存在的问题
虽然这种使用Cookie+Session的方式完成了登录验证,但仍然存在一些问题:
因为服务端需要对接大量的客户端,就需要存放大量的SessionId,会导致服务端压力过大。
若服务端是一个集群,需要将SessionId同步到每一台机器上,增长了集群服务端维护成本。
因为SessionId存放在Cookie中,因此没法避免CSRF攻击。
CSRF攻击是一种利用用户在目标网站上已认证的会话执行非预期操作的攻击方式。攻击者通过欺骗用户使其在受信任的网站上执行恶意操作,如转账、修改账户信息等。
常见的CSRF攻击方式,如下:
1、直接链接方式,攻击者通过诱使用户点击恶意链接,向目标网站发送伪造请求。当用户点击链接时,浏览器会自动发送包含用户认证信息的请求,从而执行攻击者指定的操作。
2、图片/资源引用方式,攻击者将恶意请求嵌入到图片、脚本或其他资源引用中,并将其插入到受信任网站的页面。当用户访问页面时,浏览器会自动加载并发送恶意请求。
3、表单提交方式,攻击者创建一个包含恶意请求的表单,并将其隐藏在一个看似正常的页面中。当用户在该页面上执行某些操作(如点击按钮)时,浏览器会自动提交表单,从而执行攻击者指定的操作。
二、Token+cookie
1. Token机制实现流程
用户首次登录时:
用户访问a.com/login,输入账号密码,并点击登录。
服务端验证账号密码无误,建立Token。
服务端将Token返回给客户端,由客户端自由保存。
后续访问页面时:
用户访问a.com/page时,带上第一次登录时获取的Token。
服务端验证Token,有效则身份验证成功。
————————————————
流程 :
用户登录:用户使用用户名和密码发送登录请求到服务器。服务器验证用户的身份信息,并验证成功后生成一个唯一的令牌(token)。
令牌生成:服务器生成一个包含用户身份验证信息的令牌,并将其返回给客户端 。令牌通常是一个加密的字符串,其中包含了用户的身份信息、授权信息和有效期 等。
令牌存储:服务器将生成的令牌存储在服务器端的缓存或数据库 中,以便后续验证和访问控制。
令牌传递:客户端将接收到的令牌存储在本地,通常可以使用Cookie或LocalStorage 等技术来存储。
请求验证:当客户端发送后续请求到服务器时,需要将令牌放在请求中的请求头、参数或Cookie中,以便服务器进行验证。
令牌验证:服务器接收到请求后,从请求中获取令牌,并与服务器存储的令牌进行比较和验证 。验证包括检查令牌的有效性、合法性以及是否过期等。
授权访问:如果令牌验证通过,服务器会根据令牌中的身份信息进行授权验证,以确定用户是否有权限进行请求的操作。
响应返回:服务器根据验证和授权结果返回相应的响应结果给客户端。
2.Token 机制优点缺点:无状态性、跨平台支持、安全性。复杂Token 管理、泄露风险、传输安全
优点:
——无状态性(Statelessness): Token 机制是无状态的,服务器不需要保存用户的会话状态,因此可以降低服务器的负载,特别适用于分布式系统和微服务架构。
——跨平台和跨域支持: Token 可以在各种平台和环境下使用,并且可以跨越不同的域,适用于各种前端和后端技术栈。
——安全性: Token 可以使用加密算法进行签名和验证,确保数据的完整性和安全性。此外,可以设置 Token 的过期时间和权限范围,增强了安全性。
——可扩展性: Token 机制灵活且可扩展,可以根据业务需求定制不同的 Token 格式和验证规则,支持多种身份验证方式。
——用户体验: Token 机制使用户可以长时间保持登录状态,无需频繁登录,提高了用户的使用体验。
缺点:
——Token 管理复杂: 使用 Token 机制需要额外的逻辑来生成、验证和管理 Token,相比传统的基于会话的认证方式,实现和维护成本更高。Token下发之后,只要在生效时间内,就一直生效,若服务端想要收回此Token权限,并不容易。
——Token 泄露风险: 如果 Token 被泄露,攻击者可以利用 Token 进行未授权的访问,因此需要采取措施来保护 Token 的安全性,如使用 HTTPS 加密传输、定期更换 Token 等。
-——Token 的传输安全: Token 通常是在 HTTP 头部或请求参数中传递的,如果未经加密,可能被中间人攻击截获或篡改,造成安全风险。
——Token 长期性: Token 通常具有较长的有效期,如果长时间不使用或泄露,可能会增加安全风险,因此需要定期更新 Token 或采取其他有效期管理策略。
3. Token的生成方式
随机字符串生成
JWT(JSON Web Token)
OAuth 2.0,
OIDC(OpenID Connect)——OIDC 是建立在 OAuth 2.0 基础上的身份验证协议,使用 JWT 作为身份验证令牌。OIDC 的身份验证令牌通常称为 ID Token,用于传递用户身份信息和认证状态。
基于时间戳的 Token——可以根据当前时间戳和用户信息生成 Token,并设置过期时间,保证 Token 的时效性。
最常见的Token生成方式是使用JWT,JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息 ,也可以增加一些额外的其他业务逻辑所必须的声明信息,该token也可以直接被用于认证,也可被加密
JWT
算法主要分为3个部分:
header
(头信息)——令牌的类型(即 "JWT")和所使用的签名算法(如 HMAC SHA256 或 RSA)。头部使用 Base64 编码后的 JSON 字符串表示。
playload
(消息体)——包含了 JWT 的声明信息,包括了一些标准的声明(例如过期时间、发行人、主题等),也可以包含自定义的声明。
signature
(签名)——JWT的签名,主要为了让JWT不能被随意篡改。签名通常是由头部、载荷和密钥一起进行加密生成的。签名的生成算法取决于头部中指定的算法,常见的有 HMAC SHA256 和 RSA。
三、单点登录(Single Sign On——一次登录,全线通用)
当业务线越来也多,就会有更多业务系统分散到不同域名下(不同的系统),就需要(一次登录,全线通用)的能力,这就是单点登录。
1、“虚假的单点登录”,使主域名相同
cookie是有限制的,这个限制就是cookie的域(通常对应网站的域名),浏览器发送http请求时会自动携带与该域匹配的cookie,而不是所有cookie 。
因此,我们可以将web应用群中所有子系统的域名统一在一个顶级域名下,采用同域名共享cookie的方式。这样也能实现一次登录,全线通用。
但是共享cookie的方式存在众多局限:
所有的子系统域名要统一;
应用群各系统使用的技术要相同,并且共享cookie的方式是无法实现跨语言技术平台登录的
2、“真实”的单点登录
当主域名不同时,实现一次登录,全线使用,这才是真正的单点登录。在这种场景下,我们需要独立的认证服务,通常被称为 SSO(Single Sign On)
- 当用户访问A系统,没有登录凭证(ticket),A系统让它重定向到SSO
- 用户没有在SSO登录,SSO系统下就没有凭证(这个和ticket不是一个东西),用户输入账号和密码进行登录
- SSO校验账号密码成功,通过接口返回,做两件事:一在SSO系统种下凭证(记录用户的登录状态);二是给用户下发一个ticket
- 客户端拿到tikcet,保存起来,带着ticket再次访问系统A
- SSO校验ticket,成功后正常处理业务请求
- 此时用户第一次访问系统B,没有ticket,B系统让它重定向到SSO
- 因为用户在SSO登录过,SSO有凭证,不用再次登录,只需要下发ticket
- 客户端拿到ticket,保存起来,带着ticket请求系统B
- SSO校验ticket,成功后正常处理业务请求
只有SSO有登录账号密码的功能,其他系统都没有。用户在SSO登录后,SSO就会存储一个用户的登录凭证(这个是全局会话),然后根据重定向过来的地址,颁发要访问的系统的ticket。比如用户是从A系统重定向过来的,就颁发一个A系统的ticket(局部会话),客户端带着这个ticket就可以访问A系统了;当用户要访问B系统时,B系统将它重定向到SSO,已经登录了,所以SSO直接颁发可以访问B系统的ticket,客户端带着这个ticket就可以访问B系统了。这样就实现了一处登录,全线使用
但是这样有一个问题,SSO放回的ticket,浏览器要如何存,因为有很多个域名下,如何才能在下次访问A系统时带上这个ticket?因为浏览器对跨域有严格限制,所以我们需要在A域下保存这个A的ticket
- 在 SSO 域下,SSO 不是通过接口把 ticket 直接返回,而是通过一个带 code 的 URL 重定向到系统 A 的接口上 ,这个接口通常在 A 向 SSO 注册时约定
- 浏览器被重定向到 A 域下,带着 code 访问了 A 的 callback 接口,callback 接口通过 code去SSO中 换取 ticket
- 这个 code 不同于 ticket,code 是一次性的,暴露在 URL 中,只为了传一下换 ticket,换完就失效
- callback 接口拿到 ticket 后,在**自己的域下 set cookie ** 成功
- 在后续请求中,浏览器只需要把 cookie 中的 ticket 解析出来,然后去SSO 中 验证就可以了
当某个产品c.com
退出登录时:
- 清空
c.com
中的登录态Cookie。 - 请求认证中心
sso.com
中的退出api - 认证中心遍历下发过
ticket
的全部产品,并调用对应的退出api,完成退出。
单点登录SSO-CSDN博客
四、Oauth2.0权限认证
OAuth2权限认证(第三方登录)——70%-CSDN博客