跳到主要内容
Q drop
登录
认证 / 安全

会话管理

概要

会话管理(session management),是弥补 HTTP“无状态”的性质、跨请求保持用户登录状态的机制。HTTP 本来每个请求都是独立的,不带有前后的上下文。在会话管理中,认证成功时服务器会发放一个唯一的会话 ID,保存在浏览器的 Cookie 里。之后的请求中,服务器验证 Cookie 里包含的会话 ID,把它当作已登录的用户来处理。

会话 ID 的生成与保存

会话 ID 要用密码学上安全的随机数生成器来生成。会使用 UUID v4 或 256 位的随机字节串等。可预测的会话 ID(连续编号、基于时间戳等)会成为会话劫持攻击的目标,所以要避免使用。

在服务器端,把与会话 ID 关联的用户信息保存在数据库或内存存储中。使用 DynamoDB 这样的 NoSQL 数据库时,把会话 ID 设为分区键,并设置 TTL(有效期)来自动删除过期的会话,这样的设计很高效。

Cookie 的安全属性

会话 Cookie 需要设置多个安全属性。HttpOnly 属性禁止 JavaScript 访问 Cookie,降低会话 ID 因 XSS 攻击被窃取的风险。Secure 属性限制 Cookie 只在 HTTPS 通信中发送。SameSite 属性缓解 CSRF 攻击。

这些属性哪怕忘了设置 1 个,会话劫持的攻击面就会扩大。尤其是缺少 HttpOnly 时,XSS 漏洞被利用时,会话 ID 可能会被脚本读取。最好默认把安全属性全部启用,除非有明确的理由,否则不要禁用。

与 JWT 的比较

作为会话管理的替代方案,有 JWT(JSON Web Token)。JWT 不在服务器端保存会话信息,而是把用户信息包含在令牌本身里。服务器只要验证令牌的签名就行,所以不需要查询数据库。

但 JWT 有一个结构上的弱点:无法立即让已发放的令牌失效。用户修改了密码,或检测到非法访问时,要强制让现有的令牌失效,就需要黑名单之类的机制,这部分就要在服务器端持有状态。在会话管理中,只要从数据库中删除会话 ID,就能在服务器端让该会话失效。

这篇文章对你有帮助吗?

相关术语

相关文章

想创建你自己的提问箱吗?

只需邮箱地址即可注册,无需密码。

免费开始