44

我看到 iframe/p3p 技巧是最流行的技巧,但我个人不喜欢它,因为 javascript + 隐藏字段 + 框架真的让它看起来像一个 hack 工作。我还遇到了使用 Web 服务进行通信的主从方法(http://www.15seconds.com/issue/971108.htm),它似乎更好,因为它对用户透明并且对不同的浏览器很健壮。

有没有更好的方法,每种方法的优缺点是什么?

4

8 回答 8

63

我的方法将一个域指定为“中心”域,将任何其他域指定为“卫星”域。

当有人单击“登录”链接(或显示持久登录 cookie)时,登录表单最终会将其数据发送到中心域上的 URL,以及一个隐藏的表单元素,说明它来自哪个域(只是为方便起见,用户随后会被重定向回来)。

然后,中心域的该页面继续设置会话 cookie(如果登录顺利)并重定向回用户登录的任何域,并在 URL 中使用专门生成的令牌,该令牌对于该会话是唯一的。

然后,卫星 URL 上的页面检查该令牌以查看它是否确实对应于为会话生成的令牌,如果是,它会在没有令牌的情况下重定向到自身,并设置本地 cookie。现在,卫星域也有一个会话 cookie。此重定向会清除 URL 中的令牌,因此用户或任何爬虫都不太可能记录包含该令牌的 URL(尽管如果他们这样做了,那也没关系,令牌可以是一次性令牌)。

现在,用户在中心域和卫星域都有一个会话 cookie。但是如果他们访问另一颗卫星呢?好吧,通常情况下,它们在卫星看来是未经身份验证的。

但是,在我的整个应用程序中,每当用户处于有效会话中时,所有指向其他卫星域上的页面的链接都会附加一个 ?s 或 &s 。我保留这个's'查询字符串的意思是“与中央服务器核对,因为我们认为这个用户有一个会话”。也就是说,在任何 HTML 页面上都不会显示令牌或会话 ID,只有无法识别某人的字母“s”。

如果还没有有效的会话,接收到这样一个 's' 查询标签的 URL 将重定向到中央域,说“你能告诉我这是谁吗?” 通过在查询字符串中放入一些东西。

当用户到达中央服务器时,如果他们在那里通过身份验证,中央服务器将简单地接收他们的会话 cookie。然后它将使用另一个一次性令牌将用户发送回卫星,卫星将像登录后的卫星一样对待它(见上文)。即,卫星现在将在该域上设置会话 cookie,并重定向到自身以从查询字符串中删除令牌。

我的解决方案无需脚本或 iframe 支持即可工作。它确实需要将“?s”添加到用户可能在该 URL 上还没有 cookie 的任何跨域 URL。我确实想到了一种解决方法:当用户第一次登录时,围绕每个域设置一个重定向链,为每个域设置一个会话 cookie。我没有实现这一点的唯一原因是它会很复杂,因为您需要能够设置这些重定向发生的顺序以及何时停止,并且会阻止您扩展到超过 15 个域左右(太多了,您将危险地接近许多浏览器和代理的“重定向限制”)。

后续说明:这是 11 年前写的,当时网络非常不同 - 例如,XMLhttprequest 不被视为您可以依赖的东西,更不用说跨域了。

于 2009-02-26T12:47:38.430 回答
2

如果您可以完全控制所有域后端,那么这是一个很好的解决方案。在我的情况下,我只有一个客户端(javascript/html)控制,另一个完全控制,因此我需要使用 iframe/p3p 方法,这很糟糕:(。

于 2009-01-02T05:36:00.227 回答
1

好的,我似乎找到了解决方案,您可以创建一个脚本标签来加载您想要设置/获取 cookie 的域的 src ... 到目前为止,只有 safari 似乎无法设置 cookie,但是 Ie6 和 FF工作正常...如果您只想获取 cookie,这是一个非常好的方法。

于 2009-01-02T16:12:33.600 回答
1

那篇文章中的示例对我来说似乎很可疑,因为您基本上重定向到一个 url,而该 url 又将变量在查询字符串中传递回您的域。

在示例中,这意味着恶意用户可以简单地导航到http://slave.com/return.asp?Return=blah&UID=123 " 并以用户 123 的身份登录 slave.com。

我是否遗漏了某些东西,或者众所周知,这种技术是不安全的,不应该用于该示例所暗示的事情(传递用户 ID,大概是为了使一个人的身份可移植)。

于 2009-10-22T22:37:14.853 回答
1

@thomasrutter

您可以通过调用 ajax 来检查页面加载时的“中央”域的身份验证状态,从而避免必须管理卫星上的所有出站链接(通过将“s”附加到查询字符串)。您可以通过每个会话只进行一次调用来避免冗余调用(在后续页面加载时)。

在页面加载之前进行身份验证检查请求服务器端可能会更好,这样(a)您可以更有效地访问会话,并且(b)您将在页面呈现时知道用户是否登录(并相应地显示内容)。

于 2012-09-05T03:49:49.493 回答
0

我们使用 cookie 链接,但这不是一个好的解决方案,因为当其中一个域对用户不起作用时(由于过滤/防火墙等),它会中断。较新的技术(包括您的技术)仅在分发 cookie/管理登录的“主”服务器中断时才会中断。

请注意,您的 return.asp 可能会被滥用以重定向到任何站点(例如,请参阅this )。

于 2009-01-02T05:52:53.783 回答
0

您还应该针对域 b、c、d、... 验证活动会话信息,这样您只有在用户已经登录域 a 时才能登录。

于 2011-02-23T15:21:17.180 回答
-3

您所做的是在接收您检查引荐来源地址的变量的域上,以便您可以确认链接来自您自己的域,而不是简单地将链接输入地址栏中的人。这种方法效果很好。

于 2010-10-19T22:17:17.890 回答