真实面经题目 · 原创解析

如何确保cookie不重复?

确保 cookie 不重复,不能只理解为 cookie 名字不要重复。浏览器实际以 name、Domain、Path 作为主要唯一键;同一组键再次 Set-Cookie 会覆盖旧值,但同名 cookie 如果 Domain 或 Path 不同,可以同时存在,并在请求时一起进入 Cookie 请求头。面试中应回答:统一 cookie 的 name、Domain、Path,更新时使用相同属性覆盖;清理历史重复项时按旧 Domain/Path 组合逐个过期;服务端用高熵随机值和存储层唯一约束保证 sessionId/token 唯一。

出现于:阿里巴巴 · 算法

60 秒回答模板

可以从两层回答。第一,浏览器不会按 cookie 名单独去重,真正决定覆盖的是 name + Domain + Path。要避免同名重复,就必须统一设置 Domain 和 Path,例如始终使用同一个 Domain、Path=/,后续更新用相同属性重新 Set-Cookie;如果历史上存在不同 Path 或 Domain 的同名 cookie,需要分别用 Max-Age=0 或 Expires 过期删除。第二,如果问题指的是 cookie 中保存的 sessionId 或 token 不重复,应该由服务端生成高熵随机值,使用安全随机数、足够长的位数,并在存储层加唯一索引或缓存原子写入校验,避免并发签发冲突。实际项目还要避免前端脚本重复写 cookie、避免多个服务使用不同 Domain/Path、避免网关和业务服务同时下发同名 cookie。

考点 先区分两种不重复
主线 浏览器覆盖规则
易错点 只说 cookie 名称不能重复,忽略了 Domain…

深入解析

01

先区分两种不重复

cookie 不重复通常有两层含义:一是浏览器里不要出现多个同名 cookie,二是 cookie 里承载的 sessionId、登录态 token、追踪 ID 等值不能和其他用户重复。前者是 HTTP Cookie 存储规则问题,核心看 name、Domain、Path;后者是服务端唯一标识生成问题,核心看随机性、并发控制和存储约束。回答时先澄清这两层,会比只说使用 UUID 更准确。

02

浏览器覆盖规则

浏览器接收 Set-Cookie 后,并不是看到同名 cookie 就一定覆盖。只有新的 cookie 与旧 cookie 的 name、Domain、Path 这一组标识一致时,才会替换原来的值。如果 name 相同但 Path 不同,例如一个是 /,一个是 /api,浏览器可以同时保存;如果 Domain 不同,例如 host-only cookie 和父域 cookie,也可能同时存在。服务端收到请求时 Cookie 请求头只带 name=value,不带 Domain 和 Path,因此同名值会造成解析歧义。

03

统一写入属性

要确保同名 cookie 不重复,最重要的工程做法是所有写入点使用完全一致的属性。比如登录、刷新登录态、网关续期、退出登录都应使用相同的 cookie 名、Domain、Path、Secure、SameSite 等策略,尤其 Domain 和 Path 不能在不同模块里随手写。一般会把认证 cookie 约定为固定名称、固定 Domain、Path=/,这样后续 Set-Cookie 才是覆盖而不是新增另一个同名 cookie。

04

清理历史重复

如果线上已经产生了重复 cookie,不能只删除当前 Path 下的一个值。删除 cookie 的本质也是重新 Set-Cookie 一个同 name、Domain、Path 的过期版本,因此必须针对历史上可能出现过的 Domain 和 Path 组合分别下发删除指令。例如曾经写过 /、/api、/user 三个路径,就要分别让这些路径下的同名 cookie 过期。否则用户浏览器里会残留旧值,服务端仍可能收到多个同名 cookie。

05

服务端唯一值生成

如果问题关注的是 cookie 值不重复,例如 sessionId 不重复,应该由服务端生成,而不是让客户端拼接时间戳或用户信息。常见方案是使用密码学安全随机数生成足够长的不可预测 token,或者使用成熟的 UUID v4、ULID、Snowflake 等 ID 策略,但登录态更强调随机不可猜测。生成后最好写入集中式 session 存储,并依赖唯一约束或原子写入确认没有冲突。

06

并发和幂等控制

高并发场景下,重复问题不只来自随机碰撞,还可能来自重复登录、接口重试、多个服务同时刷新 cookie。更稳的做法是让登录态签发流程具备幂等性:同一次认证请求只生成一次 token,刷新登录态只延长或轮换既定 token,服务端存储使用唯一索引、SETNX、事务或 CAS 控制并发写入。这样即使请求重放或网关重试,也不会产生多份冲突状态。

07

解析侧容错

即使写入侧已经规范,服务端解析 Cookie 请求头时也要考虑历史遗留和异常客户端。因为请求头中多个同名 cookie 的顺序和选择可能受 Path 长度、浏览器实现、代理转发影响,业务代码不应随意取第一个或最后一个就认为正确。更稳妥的方案是在迁移期检测重复同名 cookie,优先选择符合当前签名、版本、作用域约定的值,同时下发清理指令,逐步消除脏状态。

易错点

  • 只说 cookie 名称不能重复,忽略了 Domain 和 Path 才是覆盖判断的关键。
  • 认为浏览器会自动按 name 全局去重,实际同名不同作用域可以长期共存。
  • 删除 cookie 时只设置一个过期值,没有覆盖历史上写过的全部 Path 和 Domain。
  • 用时间戳、用户 ID 或自增数字生成登录 token,导致可预测或并发冲突风险。
  • 多个服务各自 Set-Cookie,缺少统一配置,最终写出多个同名但作用域不同的值。
  • 服务端解析 Cookie 请求头时随便取第一个值,没有处理重复同名 cookie 的异常情况。

面试官追问

为什么浏览器里会出现两个同名 cookie?

最常见原因是同名 cookie 使用了不同 Domain 或 Path。比如一个服务设置 Path=/,另一个服务设置 Path=/api,它们不会互相覆盖;或者一个是当前主机的 host-only cookie,另一个是父域 cookie,也可能共存。请求发送时 Cookie 头不携带 Domain 和 Path,服务端只看到多个同名 name=value,于是产生歧义。

如何删除一个已经重复的 cookie?

删除 cookie 不是按名字全局删除,而是给同一个 name、Domain、Path 下发一个已经过期的 Set-Cookie。因此要先梳理历史版本可能用过哪些 Domain 和 Path,然后分别设置 Max-Age=0 或过去的 Expires。只删 Path=/ 的版本,无法删除 Path=/api 或其他路径下的同名 cookie。

sessionId 用 UUID 就一定不会重复吗?

UUID v4 在位数足够、随机源可靠时碰撞概率极低,但工程上不能只靠概率很小作为完整答案。更严格的做法是使用安全随机数生成 token,并在 session 存储、数据库或缓存中加唯一约束和原子写入校验。若发现冲突则重新生成,这样唯一性由生成算法和存储层共同保证。

Cookie 重复会造成什么问题?

重复 cookie 会让服务端解析不确定,可能不同语言框架取第一个、最后一个或合并后的值,导致用户登录态异常、退出后仍被旧 cookie 登录、灰度环境串状态等问题。对于认证场景,重复值还可能扩大安全风险,因为旧 token 残留时,业务以为已经更新,实际请求仍可能带着旧身份信息。

网关和业务服务都要设置 cookie 时怎么办?

应明确 cookie 的所有权,最好由一个统一层负责认证 cookie 的签发、续期和删除,业务服务只读取或通过接口申请变更。如果必须多处写入,就需要抽出统一配置,确保 name、Domain、Path、SameSite、Secure 等完全一致,并用测试覆盖登录、刷新、退出、跨子域访问等关键链路。