我在不同域中有多个站点:example.com
、example.org
和. 所有网站都具有共同的外观和感觉,并且应该共享相同的用户群。mail.example.com
passport.example.org
在这种极端情况下,我仍然希望所有站点透明地(尽可能)共享具有以下关键属性的用户会话:
单点登录。当用户
passport.example.org
登录并访问任何其他网站时——他应该被视为已登录。登录的用户会
$username
在网站标题和不同的导航菜单中看到“你好”问候语,列出他们可以访问的服务。如果他没有登录,则会出现一个“登录”链接,而不是问候,指向passport.example.org/signon
。受信任域的列表是已知的,因此无论是使用 OpenID 还是使用一些自制的轻量级协议来实现都相当简单。当用户第一次访问该站点时,我会将他重定向到位于 的特殊身份验证端点
passport.example.org
,然后它会默默地将他重定向回来,其中包括身份信息(或“未登录”匿名身份)。对于大多数浏览器来说,这是完全透明的。显然,我使用 nonce 值来对抗重定向循环。单签。当用户在下次访问任何站点时单击任何站点标题中的“注销”时 - 他应该被视为“未登录”。
OpenID 不是为此而设计的。我目前的想法(我已经有一个部分工作的实现)不是发送用户身份,而是发送“全局”会话令牌并在数据库中共享全局会话表(global_session_token ↔ 用户关系)。
机器人和无 cookie 用户支持. 网站有公共区域,用户代理应该可以在没有任何 cookie 支持的情况下访问这些区域。
正因为如此,我在 (1) 中提到的重定向成为一个问题,因为对于每个单独的页面请求,我最终都会将用户代理扔到身份验证端点并返回。这不仅会使机器人感到困惑,而且会很快用出生时死掉的会话污染我的会话数据库。而且我绝对不想显示“嘿,你没有启用 cookie,走开!” 页面,那将是非常粗鲁和令人失望的。虽然我需要 cookie 支持才能登录,但我希望用户可以自由阅读网站的用途等等——没有任何限制。
除了我提到的一些透明的跨域重定向之外,我明确不想将会话 ID 放在 URL 中。我相信这样做是一个安全问题,而且通常是一件坏事。
在这里,我几乎没有想法。
好的,我知道这很难,但 Google 实际上以某种方式使用 ( google.com
、
google.
很多 gTLD等等gmail.com
),对吗?所以这应该是可能的。
我将感谢协议描述想法(那将是最好的)或系统链接(阅读代码或只是观看和学习的实时站点)已经成功实现了这样的东西。
总结一下:几个没有共同根的域,共享用户群,单点登录,单点注销,匿名浏览不需要cookie。
所有站点都在同一个网络上(但位于不同的服务器上)并部分共享同一个 PostgreSQL 数据库(位于同一数据库的不同方案中)。大多数网站都是用 Python/Django 编写的,但其中一些网站使用 PHP 和 Ruby on Rails。虽然我正在考虑一些与框架和语言无关的东西,但我很感激指出任何实现。即使我无法使用它们,如果我知道它是如何在那里完成的,也许我将能够实现类似的东西。