公开资料页

Odoo 用户资料页为什么不是公开名片:隐私开关、karma 门槛与邮箱验证主链路讲透

Odoo 的 website_profile 不是简单把用户资料公开到网站。它同时处理资料公开开关、访问 karma 门槛、头像读取边界、邮箱验证 token 和徽章排行展示,是一套“可见但有限”的公开身份系统。

网站
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

很多人第一次看到 Odoo 的用户资料页,会以为这是一个“论坛社区功能的小页面”:

  • 用户能公开头像和简介;
  • 别人可以点进去看;
  • 完成。

website_profile 真正做的事情,比公开个人主页复杂得多。

它同时处理:

  1. 用户是否主动公开自己的资料;
  2. 当前访问者有没有足够 karma 看别人资料;
  3. 头像读取是否允许走 sudo;
  4. 用户能编辑哪些字段、哪些字段不能碰;
  5. 邮箱验证成功后如何奖励 karma;
  6. 徽章与等级页面如何只展示网站可发布内容。

所以 website_profile 的核心不是“把用户挂到网站上”,而是:

在公开身份、社区激励和隐私边界之间,做一个有限开放的资料系统。


一、为什么“资料存在”不等于“任何人都能看”

_check_user_profile_access() 这段逻辑很能说明 Odoo 的态度。

它不是先问“有没有这个用户”,而是依次判断:

  • 当前访问的是否就是本人;
  • 资料是否 website_published
  • 当前访问者的 karma 是否达到 website.karma_profile_min
  • 用户记录是否真实存在。

这背后的意思很明确:

资料页不是天然公开页面

即便一个用户已经存在,也不代表网站访客就应该看到他的资料。

“是否公开”比“是否存在”更优先

源码里甚至先检查 website_published,再去处理后续访问逻辑。这说明公开开关是第一层边界。

社区不是完全开放的

想看别人资料,不只是对方要公开,你自己也得有足够 karma。

这是一种很典型的 Odoo 设计:

  • 不是绝对匿名开放;
  • 也不是完全封闭;
  • 而是用社区积分构建逐步开放的可见性。

二、为什么自己永远能看自己的资料

同一段访问检查里,有个特别重要的优先条件:

  • 如果访问者就是自己,直接允许访问。

这非常合理。

因为资料页同时还是“自助编辑入口”的一部分。

如果系统把“对外可见性”与“本人可管理性”混为一谈,就会出现一个荒唐结果:

  • 你把资料设成私密后,自己也看不到和改不了。

Odoo 明确避免了这个问题。

所以这里的设计边界是:

  • 公开访问权限本人管理权限 是两套逻辑,不该互相覆盖。

三、为什么邮箱验证不是为了登录,而是为了社区可信度

res_users.py 里,_send_profile_validation_email()_process_profile_validation_token() 组成了一条非常有意思的链路。

它们不是在做“注册激活”,而是在做:

  • 资料邮箱验证;
  • 验证成功后给用户增加 VALIDATION_KARMA_GAIN

而生成 token 的方式也很讲究:

  • 基于当天日期;
  • 基于一个系统级 website_profile.uuid
  • 再加 user_idemail
  • 生成哈希。

这说明它追求的不是长期永久 token,而是:

  • 一个和当前身份、当前邮箱、当前日期绑定的短期验证凭证。

为什么这么设计?

因为资料邮箱验证的商业意义,不是“让你能登录系统”,而是:

让社区知道,这个公开资料至少经过一次有效邮箱确认。

所以验证成功加 karma,本质上是在给可信度打分。


四、为什么资料编辑不是想改什么就改什么

save_edited_profile() 并不会把前端传来的字段全量写回。

它会先做预处理,再从 user._self_accessible_fields() 的白名单里筛可写字段。

常见可编辑内容包括:

  • name
  • website
  • email
  • city
  • country_id
  • website_description
  • website_published

而且还有额外限制:

  • 只有本人能改自己的隐私开关;
  • 某些情况下国家不能随意改;
  • 非白名单字段直接不会进入 write。

这说明资料页编辑不是“前台自由写用户表”,而是一种非常克制的 self-service。

这对网站安全很关键。


五、为什么头像读取单独走一套权限判断

/profile/avatar/<user_id> 这条路由并不简单返回图片。

它会先检查字段是否允许,再根据访问条件决定是否用 sudo 去读图像流。

这说明在 Odoo 看来,头像虽然是“看起来最公开”的资源,但也仍然属于受控资料的一部分。

这是一个很值得借鉴的细节:

  • 不要因为资源是图片,就默认它不需要权限边界。

尤其是在用户资料、员工资料、客户门户这类场景里,头像往往也是身份数据的一部分。


六、为什么徽章和等级页只展示 website_published 内容

website_profile 里,徽章相关逻辑会显式加上:

  • website_published = True

这意味着:

  • 后台存在的 badge,不代表前台都该公开;
  • 社区激励内容也需要走网站发布边界。

这个设计和资料页本身是一致的:

  • 不是有数据就展示;
  • 而是先确认这份数据被允许进入网站公开空间。

这也是为什么 Odoo 的社区/网站功能虽然看着轻,但内部其实一直在坚持“发布”与“存在”分离。


七、karma_profile_min 为什么是一个很聪明的设置

网站对象上有个字段:

  • karma_profile_min

它控制“查看其他用户资料”所需的最低 karma。

这不是一个花哨参数,而是社区治理参数。

它解决的是一个很现实的问题:

  • 完全开放资料页,容易变成低质量爬取目标;
  • 完全关闭资料页,又会损失社区互信和身份沉淀。

而 karma 门槛提供了一个中间地带:

  • 先参与社区;
  • 再逐步获得更多可见性权限。

这比“开放/关闭”二选一更细腻,也更符合 Odoo 社区产品的气质。


八、做资料页定制时最容易踩的坑

1)把资料页当普通 CMS 页面改

这样很容易绕开原有访问检查与白名单写入。

2)只改前端显示,不看 website_published

最后常见结果就是:私密资料被错误暴露。

3)自己实现一套邮箱验证,却不接 karma 逻辑

表面上功能做出来了,但和 Odoo 社区激励体系脱节。

4)头像、徽章、排行这些“看似公共内容”没有复用原边界

往往最容易造成隐私泄露的,不是简介文本,而是这些被误判成“天然公开”的资源。


最后一句

Odoo 的 website_profile 真正有意思的地方,在于它不是一个毫无边界的公开主页系统,而是把:

资料发布开关、访问 karma 门槛、受限自助编辑、邮箱验证加分、徽章公开边界

织成了一套“可见,但不是谁都能看;可编辑,但不是想改什么都行”的公开身份机制。

这也解释了为什么它看起来轻,实际却很适合做有社区氛围、又不想完全裸奔的网站资料系统。

DISCUSSION

评论区

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