Skip to content

Cookie 本身不需要服务器存储,但如果用于用户身份认证(如登录状态),服务器通常需要验证 Cookie 的内容。这里有两种方式来判断登录状态:

方式 1:Session 方式(服务器存储 Session,Cookie 仅存 Session ID)

流程:

  1. 用户登录后,服务器创建 Session 并存储在服务器内存、数据库或 Redis 中。
  2. 服务器生成 Session ID 并通过 Set-Cookie 发送给客户端:

Set-Cookie: session_id=abcd1234; HttpOnly; Secure

  1. 浏览器存储 session_id 并在后续请求时自动携带:

Cookie: session_id=abcd1234

  1. 服务器收到请求后,通过 session_id 查找存储的 Session 数据,确认用户身份。
  2. 如果 session_id 失效(如过期或删除),用户需要重新登录。

特点

✅ 安全性较高,用户数据存储在服务器端。 ✅ 支持服务器端管理会话(如过期自动清除)。 ❌ 服务器有存储开销,多个用户访问可能导致高负载。

方式 2:Token 方式(服务器不存储,每次请求验证 Cookie 数据)

另一种方式是服务器不存储任何 Session,而是使用 Token(如 JWT)存储用户信息,并在 Cookie 里发送给客户端。

流程:

  1. 用户登录后,服务器生成 JWT Token(包含用户 ID、权限、过期时间等),并使用密钥加密。
  2. 服务器将 JWT Token 返回给客户端,并让客户端存入 Cookie:

Set-Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...; HttpOnly; Secure

  1. 用户访问受保护资源时,浏览器自动带上 token:

Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

  1. 服务器收到请求后,解析 Token,验证签名和过期时间,判断用户身份。

特点

✅ 无状态(Stateless),服务器无需存储会话数据,支持分布式架构。 ✅ 扩展性更好,Token 可以跨域、适用于移动端。——> 这个很重要,cookie 默认不能跨域,需要设置 SameSite=None ❌ Token 可能被盗用,如果被泄露,攻击者可以伪造身份(可以使用 HttpOnly 和 Secure 限制)。 ❌ 不能主动失效,如果用户登出,Token 仍然有效,直到过期(可结合 Redis 进行黑名单管理)。

总结

方式Cookie 仅存 Session IDCookie 直接存 Token
服务器是否存储需要存储 Session不需要存储
服务器如何判断登录状态通过 session_id 找到 Session 数据解析 Token 进行验证
安全性更安全,数据存储在服务器容易被盗用,但适合分布式
适用场景Web 应用(需要服务器会话管理)分布式应用、移动端、API 认证

• 传统 Web 应用一般用 Session + Cookie,因为 服务器可以主动清除 Session,确保安全。 • JWT Token 更适合分布式架构,如微服务和移动端,但需要额外的安全措施防止 Token 泄露。

你用的是什么场景?可以根据具体需求选择合适的方法!

Cookie 可以单独使用,不一定要结合 Session,但具体能否单独使用取决于你的需求和安全性考虑。

  1. Cookie 单独使用的情况

Cookie 其实就是存储在客户端的小型文本数据,浏览器会在请求时自动携带它,因此可以单独用来存储信息。

(1) 记住用户偏好(无需 Session) • 例如存储用户的主题颜色、语言设置、字体大小等:

document.cookie = "theme=dark; path=/; max-age=31536000"; // 1 年有效

• 服务器不需要存储 Session,因为这些数据可以直接从 Cookie 读取。

(2) 简单的免登录(“记住我” 机制) • 在用户勾选“记住我”时,把用户的 user_id 存入 Cookie:

document.cookie = "user_id=12345; path=/; max-age=604800"; // 7 天有效

• 当用户下次访问时,服务器直接从 user_id 识别用户,而不使用 Session。

⚠️ 问题: • 这种方式不安全,因为 Cookie 可以被篡改(攻击者可以伪造 user_id 登录)。 • 解决方案:可以使用 签名或加密的 Cookie,如:

user_id=12345;signature=abcdefg

服务器验证 signature 是否正确,防止篡改。

  1. Cookie 结合 Session 使用(更安全)

(1) 维护用户登录状态 • 服务器存储用户信息,Cookie 只存 session_id:

Set-Cookie: session_id=abcd1234; HttpOnly; Secure

• 当用户访问网站时,服务器读取 session_id,找到对应的 Session 数据,确认用户身份。

⚠️ 优点: • 更安全,因为敏感信息(如用户名、权限)都在服务器,不会暴露在 Cookie 里。 • 支持登出,服务器可以清除 Session,让 session_id 失效。

  1. 为什么 Cookie 单独用不如 Session 安全?
方式服务器是否存储数据是否容易被盗用是否可主动失效
Cookie 单独使用❌ 服务器不存数据⚠️ 易被篡改和盗用❌ 不能主动失效
Cookie + Session✅ 服务器存储数据✅ 更安全,数据不暴露✅ 服务器可清除 Session
  • Cookie 单独使用适合存储非敏感数据(如主题、语言)。

  • 如果要存储登录信息,建议结合 Session 或使用 Token(JWT)进行加密验证

总结

✅ 可以单独使用 Cookie,但适用于存储非敏感信息。 ✅ 登录认证建议结合 Session,因为可以防止用户篡改数据、支持主动失效。 ✅ 如果必须用 Cookie 实现登录状态,建议使用加密或签名来防止篡改。

实际项目中,登录认证几乎不会单独依赖 Cookie,而是结合 Session 或 Token 进行更安全的身份管理。

Session 为什么要结合 redis 使用?

问题:我用 redis+jwt,那本质上不是和 session 一样了嘛?

嗯,对你这样说其实有道理,就是 redis,就相当于那个表嘛。

那因为你每次 jwt 之后,你就要用 jwt 里边儿那个 userID,你要去数据库里面查一下这个 userID 在不在你数据库里。那如果你改成去 redis 里面查,它速度更快。而且,Redis 自带一个过期时间。如果这个 JWT 过期了,那它的 userID 就在 redis 里面查不出来东西,然后我们就可以认为这 jwt 已经过期了。我觉得 redis 主要是这个作用吧,就是说它并不是一个必须的东西,它的存在只是为了帮助 JWT 去判断嘛。

所以说,如果你存这 JWT 的话,它根本就不需要你在后端去存一个表儿。然后,我们现在就把 redis 理解成那个表儿,但是 JWT 它其实本身不需要。

理解:就是 jwt 本来的设计初衷就是无状态的,但是我们这个项目它本身是有对用户状态的需求的,所以解析 jwt 才需要去查数据库这个 user 是不是真实存在

对,因为你不能保证这个 user 他只要注册了,它一定永远是可以用的,那有可能我们要把这个 user 我给他注销了,我把这账户给他封了,让他不能用了。那相应的它这个 JWT 也就失效了,那我们就不能让他这个 JWT 来起作用,所以每次都要去查一下用户状态。

所以由于 jwt 它是到点才过期,它放在前端我们操作不到它,不能做到中途让它过期,所以我们才需要这样的设计!