您最喜欢的跨域cookie共享方法是什么?

时间:2023-02-03 12:27:53

I see iframe/p3p trick is the most popular one around, but I personally don't like it because javascript + hidden fields + frame really make it look like a hack job. I've also come across a master-slave approach using web service to communicate (http://www.15seconds.com/issue/971108.htm) and it seems better because it's transparent to the user and it's robust against different browsers.

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

Is there any better approaches, and what are the pros and cons of each?

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

8 个解决方案

#1


57  

My approach designates one domain as the 'central' domain and any others as 'satellite' domains.

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

When someone clicks a 'sign in' link (or presents a persistent login cookie), the sign in form ultimately sends its data to a URL that is on the central domain, along with a hidden form element saying which domain it came from (just for convenience, so the user is redirected back afterwards).

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

This page at the central domain then proceeds to set a session cookie (if the login went well) and redirect back to whatever domain the user logged in from, with a specially generated token in the URL which is unique for that session.

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

The page at the satellite URL then checks that token to see if it does correspond to a token that was generated for a session, and if so, it redirects to itself without the token, and sets a local cookie. Now that satellite domain has a session cookie as well. This redirect clears the token from the URL, so that it is unlikely that the user or any crawler will record the URL containing that token (although if they did, it shouldn't matter, the token can be a single-use token).

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

Now, the user has a session cookie at both the central domain and the satellite domain. But what if they visit another satellite? Well, normally, they would appear to the satellite as unauthenticated.

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

However, throughout my application, whenever a user is in a valid session, all links to pages on the other satellite domains have a ?s or &s appended to them. I reserve this 's' query string to mean "check with the central server because we reckon this user has a session". That is, no token or session id is shown on any HTML page, only the letter 's' which cannot identify someone.

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

A URL receiving such an 's' query tag will, if there is no valid session yet, do a redirect to the central domain saying "can you tell me who this is?" by putting something in the query string.

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

When the user arrives at the central server, if they are authenticated there the central server will simply receive their session cookie. It will then send the user back to the satellite with another single use token, which the satellite will treat just as a satellite would after logging in (see above). Ie, the satellite will now set up a session cookie on that domain, and redirect to itself to remove the token from the query string.

当用户到达*服务器时,如果他们在那里被认证,则*服务器将仅接收他们的会话cookie。然后,它将用另一个单一使用令牌将用户送回卫星,卫星将在登录后将其视为卫星(见上文)。即,卫星现在将在该域上设置会话cookie,并重定向到自身以从查询字符串中删除令牌。

My solution works without script, or iframe support. It does require '?s' to be added to any cross-domain URLs where the user may not yet have a cookie at that URL. I did think of a way of getting around this: when the user first logs in, set up a chain of redirects around every single domain, setting a session cookie at each one. The only reason I haven't implemented this is that it would be complicated in that you would need to be able to have a set order that these redirects would happen in and when to stop, and would prevent you from expanding beyond 15 domains or so (too many more and you become dangerously close to the 'redirect limit' of many browsers and proxies).

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

#2


2  

That's a good solution if you have full-control of all the domains backend. In my situation I only have client (javascript/html) control on one, and full-control on another, therefore I need to use the iframe/p3p method, which sucks :(.

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

#3


1  

The example in that article seems suspicious to me because you basically redirect to a url which, in turn, passes variables back to your domain in a querystring.

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

In the example, that would mean that a malicious user could simply navigate to http://slave.com/return.asp?Return=blah&UID=123" and be logged in on slave.com as user 123.

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

Am I missing something, or is it well-known that this technique is insecure and shouldn't be used for, well, things like that example suggests (passing user id's around, presumably to make one's identity portable).

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

#4


1  

@thomasrutter

You could avoid having to manage all outbound links on satellites (via appending "s" to querystring) by making an ajax call to check the 'central' domain for auth status on page load. You could avoid redundant calls (on subsequent page loads) by making only one per session.

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

It would be arguably better to make the auth check request server-side prior to page load so that (a) you have more efficient access to session, and (b) you will know upon page render whether or not the user is logged in (and display content accordingly).

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

#5


0  

We use cookie chaining, but it's not a good solution since it breaks when one of the domains doesn't work for the user (due to filtering / firewalls etc.). The newer techniques (including yours) only break when the "master" server that hands out the cookies / manages logins breaks.

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

Note that your return.asp can be abused to redirect to any site (see this for example).

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

#6


0  

Ok I seem to have found a solution, you can create a script tag that loads the src of the domain you want to set/get cookies on... only safari so far seems not to be able to SET cookies, but Ie6 and FF work fine... still if you only want to GET cookies, this is a very good approach.

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

#7


0  

You also should validate active session information against domains b,c,d,... this way you can only login if the user has already logged in at domain a.

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

#8


-3  

What you do is on the domain receiving the variables you check the referrer address as well so you can confirm the link was from your own domain and not someone simply typing the link into the address bar. This approach works well.

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

#1


57  

My approach designates one domain as the 'central' domain and any others as 'satellite' domains.

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

When someone clicks a 'sign in' link (or presents a persistent login cookie), the sign in form ultimately sends its data to a URL that is on the central domain, along with a hidden form element saying which domain it came from (just for convenience, so the user is redirected back afterwards).

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

This page at the central domain then proceeds to set a session cookie (if the login went well) and redirect back to whatever domain the user logged in from, with a specially generated token in the URL which is unique for that session.

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

The page at the satellite URL then checks that token to see if it does correspond to a token that was generated for a session, and if so, it redirects to itself without the token, and sets a local cookie. Now that satellite domain has a session cookie as well. This redirect clears the token from the URL, so that it is unlikely that the user or any crawler will record the URL containing that token (although if they did, it shouldn't matter, the token can be a single-use token).

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

Now, the user has a session cookie at both the central domain and the satellite domain. But what if they visit another satellite? Well, normally, they would appear to the satellite as unauthenticated.

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

However, throughout my application, whenever a user is in a valid session, all links to pages on the other satellite domains have a ?s or &s appended to them. I reserve this 's' query string to mean "check with the central server because we reckon this user has a session". That is, no token or session id is shown on any HTML page, only the letter 's' which cannot identify someone.

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

A URL receiving such an 's' query tag will, if there is no valid session yet, do a redirect to the central domain saying "can you tell me who this is?" by putting something in the query string.

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

When the user arrives at the central server, if they are authenticated there the central server will simply receive their session cookie. It will then send the user back to the satellite with another single use token, which the satellite will treat just as a satellite would after logging in (see above). Ie, the satellite will now set up a session cookie on that domain, and redirect to itself to remove the token from the query string.

当用户到达*服务器时,如果他们在那里被认证,则*服务器将仅接收他们的会话cookie。然后,它将用另一个单一使用令牌将用户送回卫星,卫星将在登录后将其视为卫星(见上文)。即,卫星现在将在该域上设置会话cookie,并重定向到自身以从查询字符串中删除令牌。

My solution works without script, or iframe support. It does require '?s' to be added to any cross-domain URLs where the user may not yet have a cookie at that URL. I did think of a way of getting around this: when the user first logs in, set up a chain of redirects around every single domain, setting a session cookie at each one. The only reason I haven't implemented this is that it would be complicated in that you would need to be able to have a set order that these redirects would happen in and when to stop, and would prevent you from expanding beyond 15 domains or so (too many more and you become dangerously close to the 'redirect limit' of many browsers and proxies).

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

#2


2  

That's a good solution if you have full-control of all the domains backend. In my situation I only have client (javascript/html) control on one, and full-control on another, therefore I need to use the iframe/p3p method, which sucks :(.

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

#3


1  

The example in that article seems suspicious to me because you basically redirect to a url which, in turn, passes variables back to your domain in a querystring.

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

In the example, that would mean that a malicious user could simply navigate to http://slave.com/return.asp?Return=blah&UID=123" and be logged in on slave.com as user 123.

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

Am I missing something, or is it well-known that this technique is insecure and shouldn't be used for, well, things like that example suggests (passing user id's around, presumably to make one's identity portable).

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

#4


1  

@thomasrutter

You could avoid having to manage all outbound links on satellites (via appending "s" to querystring) by making an ajax call to check the 'central' domain for auth status on page load. You could avoid redundant calls (on subsequent page loads) by making only one per session.

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

It would be arguably better to make the auth check request server-side prior to page load so that (a) you have more efficient access to session, and (b) you will know upon page render whether or not the user is logged in (and display content accordingly).

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

#5


0  

We use cookie chaining, but it's not a good solution since it breaks when one of the domains doesn't work for the user (due to filtering / firewalls etc.). The newer techniques (including yours) only break when the "master" server that hands out the cookies / manages logins breaks.

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

Note that your return.asp can be abused to redirect to any site (see this for example).

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

#6


0  

Ok I seem to have found a solution, you can create a script tag that loads the src of the domain you want to set/get cookies on... only safari so far seems not to be able to SET cookies, but Ie6 and FF work fine... still if you only want to GET cookies, this is a very good approach.

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

#7


0  

You also should validate active session information against domains b,c,d,... this way you can only login if the user has already logged in at domain a.

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

#8


-3  

What you do is on the domain receiving the variables you check the referrer address as well so you can confirm the link was from your own domain and not someone simply typing the link into the address bar. This approach works well.

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