我看到iframe/p3p技巧是最受欢迎的一个,但我个人不喜欢它因为javascript +隐藏字段+框架真的让它看起来像黑客工作.我也遇到过使用Web服务进行通信的主从方法(http://www.15seconds.com/issue/971108.htm),它看起来更好,因为它对用户是透明的,并且它对不同的浏览器很强大.
有没有更好的方法,每种方法的优点和缺点是什么?
我的方法将一个域指定为"中心"域,将任何其他域指定为"卫星"域.
当有人点击"登录"链接(或呈现持久登录cookie)时,登录表单最终将其数据发送到中央域上的URL,以及隐藏的表单元素,说明它来自哪个域(仅为方便起见,之后用户被重定向回来).
然后,中央域中的此页面继续设置会话cookie(如果登录顺利)并重定向回用户登录的任何域,并在URL中使用特殊生成的令牌,该令牌对于该会话是唯一的.
然后,卫星URL处的页面检查该令牌以查看它是否确实对应于为会话生成的令牌,如果是,则在没有令牌的情况下重定向到自身,并设置本地cookie.现在卫星域也有会话cookie.此重定向清除URL中的令牌,因此用户或任何爬虫不太可能记录包含该令牌的URL(尽管如果这样做,则无关紧要,令牌可以是一次性令牌).
现在,用户在中心域和卫星域都有会话cookie.但如果他们访问另一颗卫星呢?嗯,通常情况下,他们会认为卫星是未经验证的.
但是,在我的应用程序中,只要用户处于有效会话中,所有指向其他卫星域上的页面的链接都会附加?s或&s.我保留这个'''查询字符串意味着"检查中央服务器,因为我们认为这个用户有一个会话".也就是说,任何HTML页面上都不会显示任何令牌或会话ID,只会显示无法识别某人的字母's'.
如果还没有有效的会话,接收这样的's'查询标记的URL将重定向到中央域,说"你能告诉我这是谁吗?" 通过在查询字符串中放置一些东西.
当用户到达中央服务器时,如果他们在那里被认证,则中央服务器将仅接收他们的会话cookie.然后,它将用另一个使用令牌将用户送回卫星,卫星将在登录后将其视为卫星(见上文).即,卫星现在将在该域上设置会话cookie,并重定向到自身以从查询字符串中删除令牌.
我的解决方案无需脚本或iframe支持.它确实需要将"?s"添加到用户可能尚未在该URL处拥有cookie的任何跨域URL.我确实想到了解决这个问题的方法:当用户首次登录时,在每个域周围设置一系列重定向,并在每个域中设置会话cookie.我没有实现这一点的唯一原因是它会很复杂,因为你需要能够设置这些重定向会发生在何时停止的设置顺序,并且会阻止你扩展超过15个域左右(太多了,你变得危险地接近许多浏览器和代理的'重定向限制').