协同办公

Odoo 访客为什么不是匿名路人:`mail.guest` 的 Cookie 识别、在场状态与公开频道边界讲透

很多人以为 Discuss 里的 guest 只是没登录的浏览器会话。源码里的 `mail.guest` 其实有独立身份:名字、语言、时区、访问令牌、Cookie、presence,甚至还能作为频道成员存在。也就是说,guest 不是 public user 的简化版,而是一种受限但正式的协作身份。

协同办公
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Discuss 里的 guest,不是“完全匿名的人”。

Odoo 把 guest 建成了一个正式但受限的协作身份:它有名字、语言、时区、访问令牌、Cookie 识别、presence 状态,还能成为频道成员。

所以 guest 更像“外部访客身份”,而不是“未登录用户随便看看”。


一、为什么 guest 要单独成模

mail.guest 不是挂在 res.userspublic user 上的一个小补丁,而是独立模型。

它有:

  • name
  • access_token
  • lang
  • timezone
  • channel_ids
  • presence_ids
  • im_status

这说明 Odoo 想解决的问题不是“给匿名用户一点只读权限”,而是:

  • 让外部参与者进入有限协作空间
  • 又不要求对方注册正式内部账号

源码里 guest 会通过 dgid Cookie 保存 guest_id|access_token

这套设计有两个好处:

  1. 浏览器下次回来还能被识别成同一个 guest
  2. 不是只靠裸 guest_id,降低伪造风险

这说明 Odoo 不把 guest 当成一次性临时噪音,而是允许他在一段时间内持续参与同一协作上下文。


三、为什么 guest 还能有 presence 和 IM status

很多系统会让外部访客只能“进来看消息”。

Odoo 更进一步:guest 也可以有 presence_idsim_status,还能带 scoped token 去订阅相关状态。

这背后的意义是:

对协作而言,guest 不是静态收件人,而是有在线/离线状态的真实参与者。

所以如果你在公开频道、外部协作场景里看到 guest 的在线状态变化,那不是额外插件效果,而是核心模型支持。


四、为什么 public user 不能直接当频道成员

discuss.channel.member 源码里明确拦截了 public user 进入成员列表。

这点非常关键。

Odoo 的思路不是:

  • 让公共用户直接混进频道体系

而是:

  • 内部人走 partner / user 身份
  • 外部轻量参与者走 guest 身份

这样权限边界才清楚:

  • public user 保持公共网站意义
  • guest 才承担受限协作意义

五、为什么 guest 与频道成员是正式关系

discuss.channel.member 要么绑定 partner_id,要么绑定 guest_id,不能两个都空,也不能两个都占。

这说明 Odoo 把“谁在频道里”当作严肃关系,而不是前端临时列表。

只要 guest 成了成员,就有:

  • 成员唯一性
  • 已读未读状态
  • 钉住/取消钉住
  • RTC 邀请等后续行为

六、最容易误解的地方

误区 1:guest = public user

不是。两者职责不同。

误区 2:guest 没账号,所以不算正式参与者

不是。guest 有自己一套身份与 presence 机制。

误区 3:只要是公开频道,谁都天然是成员

不是。公开加入和正式成员关系仍然是两回事。


七、排错顺序

遇到“外部访客为什么进不来 / 状态不对”时,建议按这个顺序查:

  1. 当前进来的是 public user 还是 guest
  2. 浏览器 Cookie 里的 guest 身份是否还有效
  3. guest 是否真的被加入 discuss.channel.member
  4. 相关 presence / token 是否能正常订阅
  5. 最后再看频道公开性和组授权

最后一句

Odoo 的 guest 设计,不是为了放松权限,而是为了在不发正式账号的前提下,仍然保留‘这是一个被识别、可追踪、可协作的人’。

这就是它和匿名访问最大的区别。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。