文章目录
前言
比如:我们在做在线购物网站项目或者其他需要登录信息验证的项目时,当我们登录页面进行登录之后,如果我们希望后续所有的页面都维持登录的状态,我们一般会使用
cookie
,session
,token
来实现, 如果我们都不使用,那么维持用户的登录信息是十分麻烦的,以下举例说明
不使用cookie
,session
,token
技术进行认证
- 在登录页面输入用户信息,信息通过请求传递给后端,后端进行鉴权(判断用户名和密码是否合法);
- 鉴权成功,后端向前端发送鉴权成功的信息,当前请求维持登录状态;
- 鉴权失败,后端向前端发送鉴权失败的信息;
- 而在后续请求来到后端时,由于请求之间是相互独立的,所以后续请求还需要传递用户信息给后端,并且后端还要重复进行鉴权行为.
加入我们此时登录淘宝网站,在进行登录页面的登录之后,跳转到首页,还要再输入一遍账户和密码,在首页中点击某个产品信息时,跳转产品主页信息,又需要再输入一遍账户和密码…这种情况给用户体验大打折扣,也给后端制造了频繁鉴权的压力.
cookie,session,token
在Web
开发中,这些四个术语都涉及到用户认证和会话管理:
Cookie
:Cookie
是一种小型数据存储对象,通常由服务器发送到客户端浏览器并存储在本地。当用户访问网站时,浏览器会自动将Cookie
发送回服务器,用于跟踪用户的登录状态、保存个性化设置等。然而,Cookie
的数据量有限,并且容易受到劫持。Session
:Session
是基于服务器端的会话机制,通过生成一个唯一的ID
(通常是服务器产生的)存储在服务器上,客户端在每次请求时携带这个ID
,以此保持用户的状态。Session
有生命周期,一旦超时,需要重新登录。但是,如果服务器崩溃,可能会丢失所有会话信息。Token
(包括JWT
):Token
是一种安全的身份验证机制,常用于无状态(stateless
)的API
设计中。例如JSON Web Token
(JWT
) 是一种紧凑的、自包含的方式来安全地传输信息,它包含了用户的标识和一些附加信息。JWT
通常在HTTP
头部发送,可以在服务器之间传递用户状态而无需cookie
。优点是支持跨域,易于管理和加密。
4.cookie
、session
和token
是在登录业务中的应用,cookie
主要用于本地存储,但存在安全风险;session
存储在服务器端,安全性高但扩展性差;token
(如JWT
)无状态且灵活,适合前后端分离和分布式系统。
Cookie
Cookie
认证流程
- 在登录页面,用户输入账号+密码,通过请求发送到后端进行鉴权
- 鉴权成功,后端的响应中
response:set-cookie
中携带用户信息,发送给前端,前端将cookie存储到浏览器本地 - 鉴权失败,后端向前端发送鉴权失败信息
- 鉴权成功,后端的响应中
- 在后续的请求中,请求头中会自动携带
cookie
信息,无需用户重复进行用户信息的输入
展示浏览器中的cookie
我们打开浏览器的开发者工具:
我们发现,Cookie
信息中不仅可以存储账号+密码,还有其他的一些信息,作为开发者,可以自行进行填充,以<name,value>
键值对的形式进行存储
Cookie
中存在的问题
- 安全性问题
- 明文存储:
Cookie
默认以明文形式存储在用户浏览器中,并通过HTTP
请求在客户端与服务器之间传输。这种机制使得Cookie
中的敏感信息(如用户登录凭证、会话标识等)容易被网络中的恶意第三方截获。 - 跨站脚本攻击(
XSS
):攻击者可以通过注入恶意脚本来获取用户的Cookie
信息。当用户访问被注入恶意脚本的网页时,这些脚本可以窃取用户的Cookie
,并发送给攻击者。 - 跨站请求伪造(
CSRF
):CSRF
攻击是一种利用用户在其他网站上的身份验证信息来执行非授权操作的攻击方式。攻击者可以通过伪造请求,诱使用户在另一个网站上执行某些操作,从而导致用户的Cookie
被发送到攻击者的网站。 - 会话劫持:攻击者通过获取用户的会话
ID
或Cookie
来冒充用户身份。一旦攻击者获得有效的会话ID
或Cookie
,就可以在不需要用户名和密码的情况下访问用户的账户,进行非法操作。
- 存储限制
- 大小限制:不同浏览器对单个域名下可存储的
Cookie
大小有严格的限制,一般为4KB
左右。这限制了Cookie
能够存储的数据量,特别是在需要存储大量用户信息时。 - 数量限制:浏览器对单个域名下可存储的
Cookie
数量也有限制,可能限制了网站能够设置的Cookie
数量。
- 性能影响
- 网络流量增加:每次
HTTP
请求都会自动携带Cookie
信息,如果Cookie
数据量大或请求频繁,将显著增加网络传输的数据量,从而消耗更多的带宽和服务器资源。 - 服务器负担加重:服务器需要处理每个请求中的
Cookie
信息,增加了服务器的处理负担。
-
数据类型限制
Cookie
的value
字段仅支持字符串类型,这限制了其在存储复杂数据结构(如对象、数组等)时的能力。虽然可以通过JSON
序列化等方式进行转换,但增加了处理的复杂性和开销。 -
隐私问题
Cookie
会跟踪用户访问过的所有网站,这可能引发隐私担忧。第三方(如广告商或其他用户)可能能够访问这些存储的信息,进而用于广告定向投放或其他目的。
应对策略
为了应对Cookie
存在的问题,可以采取以下策略:
- 使用
HTTPS
:确保所有涉及Cookie
的传输都通过HTTPS
进行,以加密保护Cookie
数据,防止中间人攻击。确保Cookie
仅在安全的HTTPS
连接上传输,避免在不安全的HTTP
连接中暴露敏感信息。 - 精简
Cookie
数据:仅存储必要的用户信息,避免在Cookie
中存储大量非关键数据。 - 定期更新
Cookie
:定期更新Cookie
的值和过期时间,减少攻击者利用旧的Cookie
进行攻击的机会。
Cookie
应用场景
- 用户登录状态维持:
当用户登录网站后,服务器可以通过设置一个包含认证信息的cookie
,使得用户在后续访问同一网站时不需要重新输入用户名和密码,从而实现“记住我”的功能。 - 个性化体验:
存储用户的偏好设置,例如字体大小、界面布局、主题风格等,以提供个性化的页面展示。 - 会话追踪:
记录用户的访问轨迹,用于分析用户行为、兴趣偏好或地理位置等,以便提供更符合用户需求的服务或内容推荐。 - 购物车功能:
在电子商务网站中,轻量级的购物车信息有时会被存储在cookie
中,以便用户在不同页面间切换时仍能看到已添加的商品。 - 广告追踪与分析:
第三方广告服务提供商可能会使用cookie
来追踪用户的浏览历史,以便推送定向广告或者进行网站流量分析。 - 安全性限制:
有时候cookie
被用于实施安全措施,例如CSRF
(跨站请求伪造)令牌,确保请求确实来自于已经授权的用户。 - 网站统计与分析:
Google Analytics
等网站分析工具使用cookie
来跟踪用户访问次数、新老访客识别等指标。
8 .分布式应用共享状态:
在大型网站或分布式系统中,cookie
可以帮助不同的服务器节点识别同一个用户,从而提供连续一致的服务。
Session
Session
认证流程
经过上述的学习,我们了解到:
cookie
是存储在客户端本地内存中的,会存在安全性的问题,那么如果我们将用户信息存储在服务端,是否就可以解决安全性的问题?
- 在登录页面,用户输入账号+密码,通过请求发送到后端进行鉴权
- 鉴权成功,后端将用户信息放入
session
中,并生成唯一标识(sessionid
),响应response:set-cookie(sessionid)
中携带sessionid
,发送给前端,前端将cookie(sessionid)
存储到浏览器本地 - 鉴权失败,后端向前端发送鉴权失败信息
- 鉴权成功,后端将用户信息放入
- 在后续的请求中,请求头中会自动携带
cookie(sessionid)
信息,无需用户重复进行用户信息的输入,后端拿到sessionid
后去session
中查询用户信息,维护登录状态.
session
中存在的问题
- 占用服务器资源:
Session
数据通常存储在服务器的内存中,随着用户数量的增加,服务器资源可能变得紧张,从而影响应用的性能。 - 扩展性差(在分布式集群场景下存在该问题)
接下来我们详细讲解这个问题:
我们知道,当下市场上大部分的应用程序,都不会仅仅部署在同一台服务器上,而是部署在多个服务器上,目的是为了提高了程序的高可用性和负载均衡.
这种将一个程序部署在多个节点上的操作,就叫做分布式
分布式集群是一种将计算和存储资源分散到多个节点上,通过网络连接实现协同工作的架构。
以下是分布式集群的关键原理:
- 分布式存储:将数据分散存储在多个节点上,而不是集中存储在一个节点上。这样可以提高数据的可靠性和可用性,因为即使某个节点出现故障,其他节点仍然可以提供数据。
- 负载均衡:将请求分散到多个节点上处理,以避免单个节点承担过多的负载。负载均衡可以通过轮询、加权轮询、随机等方式实现,以确保每个节点都能公平地处理请求。
所以,在分布式集群当中,请求不一定一直到达一个服务器中,而是由多个服务器共同承担请求,这时,第一次请求发送的用户信息存储在某个服务器的session中,但是并不会使得其他服务器也产生session
,所以后续请求只携带sessionid
是行不通的.
在上述的过程中,我们了解到session
在分布式集群存在的扩展性的问题,所以接下来我们来讲解一种常见的解决方案:使用Redis
作为session
缓存
所以,在集群环境下,如果使用了Session
共享机制(如Session
复制或Session
持久化),当一个节点上的Session
失效时,其他节点可能无法及时同步使其失效,从而导致Session
失效的不一致性。
4. 需要依赖 cookie
5. 跨域限制
6. 小程序不支持cookie
应对策略
- 加强安全性:
- 使用安全的传输协议(如
HTTPS
)来保护Session ID
的传输。 - 定期更新
Session ID
,降低被预测或窃取的风险。 - 实施严格的
Session
超时策略,避免长时间未使用的Session
被恶意利用。
- 提高可靠性:
- 提醒用户在公共计算机上登录后及时注销(注销后在服务端销毁对应的
session
信息)。 - 设置合理的超时时间,并根据应用需求和用户活动情况进行调整。
- 在集群环境下,采用合适的
Session
共享方案(如分布式缓存、数据库存储等)来确保Session
的同步和一致性。
- 优化性能:
- 采用分布式
Session
存储方案,减轻服务器内存压力。 - 监控服务器资源使用情况,及时扩展资源以满足用户需求。
Session
应用场景
如果是使用场景不推荐使用,消耗服务器资源,其余场景安全性较高。
以下是 session
应用场景:
- 用户登录状态管理:
当用户成功登录后,可以在服务器端的session
中存储用户的身份标识(如用户ID
)、登录状态和其他相关权限信息。每次用户发起新的请求时,服务器根据请求中携带的session ID
确认用户的身份和登录状态。 - 会话管理:
Session
可以用来跟踪用户在整个会话期间的行为,比如记录用户的浏览历史、操作记录等。一旦 会话结束(如浏览器关闭或超时),这些信息会随着session
的销毁而清除。 - 购物车功能:
用户在电商网站中选择的商品信息可以暂时存放在session
中,这样无论用户在哪一页浏览或操作,只要会话还在继续,商品信息都能保持一致,直到用户结算或清空购物车。 - 个性化设置:
保存用户的个性化配置,如页面布局、主题颜色、语言选项等临时设置,可以在整个会话过程中持续影响用户体验。 - 权限验证与访问控制:
对于需要权限验证才能访问的功能或页面,服务器利用session
中的用户角色或权限信息来决定是否允许访问。 - 防止重复提交:
在一些防止表单重复提交的场景下,可以在session
中设置一次性令牌或标记,确保用户的一个动作只被执行一次。 - 自动登录功能:
通过将session ID
持久化到cookie
(例如记住我/Keep Me Logged In
功能),允许用户在一段时间内无需重新登录即可访问受保护的内容。