example.com、example.org、mail.example.com和passport.example.org 。所有网站都有共同的外观和感觉,并且应该共享相同的用户基础。
在这种极端情况下,我仍希望所有网站都可以“透明地”(尽可能)共享用户会话,具有以下关键属性:
单点登录。当用户在passport.example.org登录并访问任何其他站点时,应视为已登录。
已登录用户在站点标题中获得“您好,$username
”,以及列出他们可以访问的服务的不同导航菜单。如果未登录,则欢迎语句改为指向passport.example.org/signon的“登录”链接。
已知可信任的域名列表,因此可以使用OpenID或一些自定义轻量级协议很容易地实现。当用户第一次访问该站点时,我将重定向到passport.example.org的特殊认证终结点,然后在包括身份信息(或“未登录”匿名身份)的情况下将其静默重定向回来。对于大多数浏览器,这是完全透明的。显然,我使用随机值来防止重定向循环。
单点注销。当用户在任何站点的标题中点击“注销”时,下次访问任何站点时,应将其视为“未登录”状态。
OpenID并不是为此而设计的。我的当前想法(我已经有了部分工作实现)是发送不是用户身份而是“全局”会话令牌,并在数据库中共享全局会话表(global_session_token ↔ user relation)。
支持机器人和无cookie用户。网站具有公共区域,应该可以被没有任何cookie支持的用户代理访问。
因此,我提到的重定向成为问题,因为对于没有接收到cookie的用户代理,它们将被重新定向到登录页面。我的解决方案是通过查询字符串参数在URL中传递会话信息,例如/some/page?session=abc123
。
每次页面请求,我都会将用户代理传递到验证端点并返回。这不仅会困惑机器人,而且会很快在我的会话数据库中污染出生即死的会话。我绝对不想显示“嘿,你没有启用 Cookie,请离开!”的页面,那会非常粗鲁和令人失望。虽然我需要支持 Cookie 才能登录,但我希望用户可以自由阅读网站内容等,没有任何限制。
此外,我明确地希望除了我提到的一些透明跨域重定向之外,不要将会话 ID 放在 URL 中。我认为这样做存在安全问题,而且通常是一个坏习惯。
目前我已经没有太多的想法了。
好吧,我知道这很难,但 Google 实际上以某种方式使用这个功能(google.com、google. 很多 gTLDs、gmail.com 等),对吧?所以,这应该是可行的。
我将非常感谢任何协议描述的建议(这将是最好的),或者是已经成功实现类似功能系统的链接(无论是可读的代码还是在线网站,供观看和学习)。
总之:多个没有共同根的域,共享用户基础、单点登录、单点注销,匿名浏览时不需要 Cookies。
所有的网站都在同一个网络上(但是运行在不同的服务器上),部分共享相同的 PostgreSQL 数据库(位于同一数据库的不同模式中)。大多数网站使用 Python/Django 编写,但是其中一些使用 PHP 和 Ruby on Rails。虽然我正在考虑一些框架和语言无关的实现方法,但如果指出任何实现方法的话,我将不胜感激。即使我不能使用它们,如果我能了解到如何在那里完成它,也许我就能想出类似的实现方法。