目录
1、核心概念
需要区分两个概念:认证 vs. 授权
-
认证:验证“你是谁?”(Authentication)。确认用户的身份,比如通过用户名和密码。
-
授权:决定“你能做什么?”(Authorization)。确认用户是否有权限访问特定资源或执行特定操作,比如是否管理员。
关于认证,主要有两个方案:
| 特性 | Session-Cookie | Token (JWT) |
|---|---|---|
| 服务器状态 | 有状态,服务器存储Session | 无状态,服务器不存储 |
| 扩展性 | 差,需要Session共享 | 好,天然支持分布式 |
| 跨域支持 | 需要额外配置 | 支持良好 |
| 安全性 | 依赖Cookie安全,需防CSRF | 依赖Token存储安全,需防XSS |
| 控制力 | 强,可随时废除Session | 弱,无法主动废除Token |
| 性能 | 每次需查询Session存储 | 只需本地计算验证签名 |
| 数据承载 | 存储在服务器,客户端只有ID | 可携带少量非敏感信息 |
2、基于Session-Cookie 的认证
2.1 工作原理
-
用户登录:客户端向服务器发送包含用户名和密码的POST请求。
-
验证凭据:服务器验证用户名和密码是否正确。
-
创建 Session:验证成功后,服务器在内存或数据库(如Redis)中创建一个Session对象,用于存储用户信息(如userId, role)。这个Session有一个唯一的标识符,称为
SessionId。 -
设置 Cookie:服务器在HTTP响应头中通过
Set-Cookie命令,将SessionId返回给浏览器。这个Cookie通常被标记为HttpOnly(防止XSS读取)和Secure(仅在HTTPS下传输)。 -
后续请求:浏览器在后续的每一次请求中,都会自动携带这个Cookie。
-
验证 Session:服务器收到请求后,从Cookie中取出
SessionId,并去Session存储中查找对应的Session数据。如果找到且有效,则认为用户已认证。 -
用户登出:用户点击退出,服务器销毁对应的Session,并通知浏览器清除Cookie。
2.2 优缺点
优点:
-
技术成熟:几乎所有Web框架都原生支持,理解简单。
-
服务器完全控制:可以随时让某个Session失效(强制下线),安全性控制力强。
-
默认短连接:Session可设置过期时间。
缺点:
-
服务器开销:需要在服务器存储所有活跃用户的Session,用户量巨大时对内存/数据库压力大。
-
不利于扩展:在分布式/集群环境中,需要做“Session持久化”或“Session粘滞”,增加了架构的复杂性。
“Session粘滞” 是一种负载均衡技术,其目的是确保来自同一个用户(或客户端)的一系列请求,都会被定向到集群中同一台后端服务器上进行处理。
对于要求高可用性和可扩展性的现代分布式系统,将会话数据外部化到如Redis这样的集中存储中,是更优、更健壮的解决方案。
-
对CSRF攻击敏感:因为认证信息自动通过Cookie携带,需要额外措施(如CSRF Token)来防御跨站请求伪造。
CSRF(跨站请求伪造):它是一种诱骗用户在已登录的Web应用中执行非本意操作的攻击方式。
攻击原理:攻击者利用了 Web浏览器的一个默认行为:会自动携带目标站点的Cookie(包括Session Cookie)来发送请求。
解决方案:增加一个攻击者无法伪造的、与用户会话相关的凭证,并在关键操作前进行验证;同源策略与Referer校验。
2.3 适用场景
-
传统的服务端渲染Web应用(如JSP, PHP, Django)。
-
不需要跨域的单体架构或能很好解决Session共享的集群架构。(Session 机制本身与“域”强绑定,它天生就不是为跨域设计的)
3、基于 Token 的认证(如 JWT)
3.1 工作原理
-
用户登录:客户端向服务器发送登录请求。
-
验证凭据并生成Token:服务器验证成功后,生成一个Token(通常是JWT格式),并将其返回给客户端。服务器不保存这个Token。
-
客户端存储Token:客户端(通常是浏览器)收到Token后,将其存储起来。常见存储位置有:
-
localStorage: 容易受到XSS攻击。 -
sessionStorage: 标签页关闭后失效。 -
安全的 Cookie(标记为
HttpOnly和Secure): 能有效防御XSS,是更推荐的方式。
-
-
后续请求:客户端在后续请求的
Authorization头部中携带Token(格式通常为Bearer <token>)。 -
验证Token:服务器收到请求后,只需验证Token的签名是否有效、是否过期,而无需查询数据库。验证通过后,即可从Token中解析出用户信息。
-
用户登出:客户端直接丢弃Token即可。服务器端无法主动让Token失效,这是其一个特点也是缺点。
3.2 JWT结构
JWT由三部分组成,用点 . 分隔:Header.Payload.Signature
-
Header: 包含令牌类型和签名算法(如HS256, RSA)。
-
Payload: 包含声明(Claims),即存放用户信息和其他元数据的地方(如userId, username, exp-过期时间)。
-
Signature: 对前两部分的签名,用于验证消息在传输过程中未被篡改。
3.3 优缺点
优点:
-
无状态/可扩展:服务器不需要存储会话信息,非常适合分布式系统和微服务架构。任何一台拥有秘钥的服务都可以验证Token。
-
多端与跨域友好:Token可以轻松地在移动端、不同域名下的前端应用之间共享(解决CORS问题)。
-
负载丰富:Payload中可以携带一些常用信息,减少数据库查询次数。
缺点:
-
Token无法主动失效:一旦签发,在过期之前一直有效。解决方法是使用短期的Token并搭配Refresh Token机制,或维护一个黑名单。
解决方案:使用短过期时间的Access Token,并搭配长过期时间的Refresh Token来更新。Refresh Token必须安全存储。
-
Token体积较大:比Session ID大得多,可能增加网络开销。
-
秘钥管理:签名秘钥的保管至关重要,一旦泄露后果严重。
-
存储安全:客户端存储需要考虑XSS攻击
XSS(跨站脚本攻击):是指攻击者利用网站开发上的漏洞,在用户使用的网页中插入并执行恶意脚本,从而盗用用户信息、冒充用户身份进行操作的一种攻击方式。攻击者可以通过这种方式窃取用户的JWT Token。
解决方案:存储在
HttpOnlyCookie中,每次请求会自动携带Cookie。
3.4 适用场景
-
前后端分离项目(React, Vue, Angular + RESTful API)。
-
移动端APP。
-
第三方单点登录(SSO)。
-
微服务架构。

235

被折叠的 条评论
为什么被折叠?



