Cookie、Session、Token、JWT 怎样区分?JWT 泄露或需要立即失效怎么办?

先理解原理和示例,再练习完整口述与追问。

Cookie 是浏览器保存并自动携带的机制;Session 是服务端保存的登录状态,通常用 Cookie 里的 session id 关联;Token 是放在请求头或 Cookie 中的凭证字符串;JWT 是一种自包含、带签名的 Token,服务端无需查库即可验证,但签发后难以提前作废。应对泄露:短有效期、刷新令牌轮换、jti 黑名单或用户令牌版本号。

Cookie 有 Domain、Path、Expires/Max-Age、Secure、HttpOnly、SameSite 等属性,HttpOnly 让 JS 读不到,SameSite 限制跨站请求携带。子域之间可以通过 Domain=example.com 共享,不同站点之间不能共享,只能通过 SSO 流程分别建立会话。

Session 把状态放在服务端,可以随时删除,多实例部署需要共享存储(如 Redis)。JWT 由 header、payload、signature 三段 Base64URL 组成,签名保证内容未被篡改,但 payload 可被任何人解码阅读,所以不能放敏感信息。JWT 的优点是无状态,缺点是无法“删掉”已经签发的令牌。

access token 有效期 15 分钟,放在内存或 HttpOnly Cookie;refresh token 存 HttpOnly、Secure、SameSite Cookie,每次刷新都签发新的并作废旧的,若旧 refresh token 被再次使用,说明可能泄露,立即撤销该用户的全部会话。需要强制下线时,服务端为用户维护 tokenVersion,令牌中携带版本,验证时与数据库比对;更换签名密钥会让所有令牌失效,适合密钥泄露时的紧急处理。

令牌放 localStorage 一旦有 XSS 就会被读走,放 Cookie 则必须防 CSRF;JWT 每次都查黑名单就失去了无状态优势,需要权衡。“同一账号只能一处登录”也是靠服务端会话版本实现,新登录使旧会话失效,并通知旧端退出。

Cookie 是浏览器存储并自动携带的机制,Session 是服务端保存的会话,靠 Cookie 中的 session id 找到;Token 是凭证本身,JWT 是自包含的签名令牌,服务端只需验签。JWT 只是签名不是加密,载荷谁都能看到。它最大的问题是签发后难以撤销,所以我会用短期 access token 加可轮换的 refresh token,配合 jti 黑名单或用户令牌版本号实现强制下线,存储位置也要在 XSS 和 CSRF 风险之间选择对应防护。