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可以单独使用吗?

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它是到点才过期,它放在前端我们操作不到它,不能做到中途让它过期,所以我们才需要这样的设计!