自动cookie单点登录多个域 - 如谷歌

时间:2012-07-11 14:27:26

标签: cookies dns single-sign-on

我不明白google如何实现以下单点登录机制:

  1. 我以gmail登录为例(我想这会创建一个带有我授权的cookie)
  2. 我打开一个新标签,直接输入“youtube”的网址
  3. 然后我输入youtube登录。
  4. 第二个站点如何检测到我已经登录。 它们是不同的领域。 Youtube无法读取Gmail的Cookie。

    我读过的关于单点登录的所有解决方案都不允许这样做。客户端始终要求获得中央登录应用程序的权限。 在我的示例中,YouTube不知道我是登录Gmail的用户(实际上它确实知道,但我不明白如何)

    请注意,我手动输入“youtube”的网址。我没有从gmail的上方工具栏中删除youtube图标(在这种情况下,gmail可能会通过网址传递一些auth params)。

5 个答案:

答案 0 :(得分:8)

Cookie是在特定域上设置的。例如:

setcookie(name,value,expire,path,domain) 

当您在“mail.google.com”之前登录gmail时,您已被重定向到“accounts.google.com”,然后重定向到“mail.google.com”,因此Cookie位于“accounts.google”上。 com“也是。

在这种情况下,域名为“accounts.google.com”,路径为“/”(主路径)。

当您请求“www.youtube.com”时,请点击它要求的“连接”  “accounts.google.com”速度很快,因此您无法看到此重定向,并检查“accounts.google.com”上是否有Cookie。如果是,它会检查cookie是否有效且未过期,或者用户未被禁止...然后它会将您重定向到“www.youtube.com/signin?loginthisSession=Sessionid”。此请求包含从“accounts.google.com”的Cookie中捕获的sessionid cookie的值。

在最后一步中,“www.youtube.com”会在域“www.youtube.com”上记录并设置自己的Cookie并保存。

所以诀窍在于302 HTTP重定向。

答案 1 :(得分:4)

可以使用中间域在域之间共享Cookie和localStorage。在主页上嵌入了一个“iframe”,它访问cookie并将消息发送到主。

mail.google.comyoutube.com可以使用accounts.google.es共享Cookie。打开Chrome->Inspect->Resources->Local storag e,您将在accounts.google.com中看到JWT格式的身份验证令牌。

我详细介绍了这个答案中的技术步骤:https://stackoverflow.com/a/37565692/6371459。另请查看https://github.com/Aralink/ssojwt以查看在中央域中使用JWT进行单点登录的实现

答案 2 :(得分:1)

检查出来.. http://www.codeproject.com/Articles/106439/Single-Sign-On-SSO-for-cross-domain-ASP-NET-applic。 本文包括SSO跨域的解释和示例。

答案 3 :(得分:0)

据我记忆,如果我没有错,cookie包含一个指定的字段,其中包含可以读取和获取此cookie的域。这样做是为了防止某些网站读取您的所有Cookie列表并开展自己的业务。您应该能够看到哪种网站可以“看到”您的Gmail密码。

如果我错了,请纠正我,这应该编写有关SID和gmail-YouTube示例的答案。

答案 4 :(得分:0)

在评估此跨域SSO主题时,我想出了可能使用 cookie加上时间戳的新的SSO同步流程。尽管它不是Google所使用的流程,但我认为可以为域数量有限的系统实现该流程。

此流程不使用3rd party cookie

这将是一长篇文章:)

举个例子,假设我们在示例宠物论坛中有以下域:

更改为https://account.domain1.com

登录步骤:

  1. 用户转到dog.domain2.com,用户尚未登录。
  2. 用户单击dog.domain2.com中的“登录”按钮
  3. 用户重定向到account.domain1.com进行登录
  4. 用户输入用户名和密码,登录成功
  5. 新步骤,在重定向回到https://dog.domain2.com之前,请在所有域上设置Cookie
    1. 将浏览器重定向到https://accounts.domain2.com?..
    2. .domains2.com域上设置一个cookie(稍后会在cookie值上提供更多信息)
    3. 将浏览器重定向到https://accounts.domain2.com?..
    4. .domains3.com域上设置cookie
    5. 将浏览器重定向到https://accounts.domain1.com?..
    6. .domains1.com域上设置cookie
    7. 重定向回原始流程
  6. 将用户重定向回其原始服务,即https://dog.domain2.com

现在,登录流程完成后,我们在所有3个域中都有Cookie 。我们的任何服务(例如https://cat.domain1.com / https://dog.domain2.com / https://rabbit.domain2.com)都可以在自己的域下访问此Cookie。

Cookie内容

  • cookie的内容应允许任何网页查看它,并确定是否需要SSO同步
  • 可以存储不同类型的Cookie内容,包括
    • 布尔值表示用户是否登录
    • 用户ID
    • 在时间戳过期

布尔值表示用户是否登录

用户ID

  • 虽然很想将user_id存储在那些cookie上,然后让所有域都可以看到它们并相应地设置用户。
    • 这太危险了,因为cookie是在父域中设置的,
    • 如果您网域下的任何网站被黑客入侵,可能会出现假冒(将任何user_id复制到其自己的浏览器cookie中)。

在时间戳过期

  • 我建议将cookie值设置为 SSO过期时间,并将类型设置为会话 cookie,这样做有以下好处:
    • 如果泄漏/更改了到期时间,对安全性的影响最小
    • 我们的网站可以检查过期时间,以了解用户是否需要重新登录
    • 关于会话cookie的原因,即当用户关闭浏览器并尝试再次登录时,该cookie将被删除,因此也注销用户
  • 任何使用SSO的网页也应自己存储具有相同过期时间的Cookie
    • 在某些情况下,User A登录后,访问https://cat.domains1.com,然后User B登录
    • 由于User AUser B的登录过期时间不同,因此存储并比较该时间戳将告诉用户再次与SSO同步

用于您服务的示例检查工具

例如在https://cat.domains1.com上,您可以将其添加到页面加载的顶部

<?php
$sso_expired_time = $_COOKIE["sso_expired_time "] ?? 0;
$website_expired_time = $_COOKIE["website_expired_time "] ?? 0;

if( (int) $sso_expired_time  < time() || $sso_expired_time  !== $website_expired_time ) {
    // User not sync, perform sync
    setcookie("website_expired_time", $website_expired_time,0,"/", $_SERVER['SERVER_NAME'], true, true);
    // Redirect to https://account.domain1.com for Login
    // Or, Initiate the login sequence for your selected login protocol
    header("Location: https://account.domain1.com/.....") 
    exit;
}
// User is sync

// Page load success, continue other operation

退出

登录与登录非常相似,基本上:

  • 注销之前,请像登录一样重定向到所有3个域
  • 删除SSO cookie
  • 继续正常的注销流程

方法的优缺点:

  • 专业版:可以同步所有域
  • 专业人士:无需依赖第三方Cookie
  • 缺点:首次登录时间更长(大约50毫秒左右)
  • 缺点:要使同步正常运行,需要在每个网站上进行自定义