如何实现 [ 跨域单点登陆 ] ?

管理用户网站javascript

用户帐户网址:http://accounts.com 用户登陆网址:http://accounts.com/login 用户等处网址:http://accounts.com/logoutphp

应用网站 应用1:http://app1.com 应用2:http://app2.comjava

实现场景 登陆 应用1,跳转到 http://accounts.com/login 进行登陆 登陆成功跳转 回应用1,地址后面会带个token,例如:http://app1.com/callback?token=xxxx 来验证登陆 浏览了 应用1 后,用户进入 应用2 (用户可能会本身输入 app2.com 的地址访问 应用2) 此时 应用2 经过“某种方式”来判断以前 应用1 的登陆与否,来设置当前用户是否登陆json

问题是如何实现场景中的 第4条?api

我如今想到的是: 同步登陆:像 discuz 那样,在登陆一个应用时对其它应用进行同步登陆,缺点是登陆后最好是等个几秒在跳转使其它应用可以有足够时间写下 cookie,可是我不喜欢“要等几秒”的方式 使用 jsonp:虽然知道怎么用 jsonp 进行跨域请求,可是实现起来有些困难,并且处理很差就有安全问题跨域

不知各位有什么好的方法???浏览器

----------------------- 华丽的分割线 --------------------------- 下午花了点时间分别研究了一下两组网站的登陆方式:安全

google.com 和 youtube.com taobao.com 和 etao.comcookie

1、 google.com 和 youtube.com 状况一:都未登陆,可是浏览过 youtube 登陆 google.com 经过 https://accounts.google.com/ServiceLoginAuth 验证用户名密码 经过验证后跳转到 https://accounts.google.com/CheckCookie 检查是否有浏览过其它应用,好比说 youtube,这时就再次跳转到 https://accounts.youtube.com/accounts/SetSID 进行登陆 最后再跳回 google.com 的首页app

状况二:已登陆 google.com,但未浏览过 youtube 也并未登陆 因为登陆了 google.com 因此我直接从地址栏里输入地址进行第一次访问 youtube 进入 youtube 首页显示的是我须要登陆,故点击登陆 依然跳转到 https://accounts.google.com/ServiceLoginAuth,可是不用任何输入直接跳回 yutube 首页

2、 taobao.com 和 etao.com 无论我有没有登陆 taobao.com,我进入 etao.com 首页,首先会检查 cookie 是否登陆 登陆则 etao.com 首页显示登陆状态 未登陆则跳转到 http://jump.taobao.com/jump?target=http%3A%2F%2Fwww.etao.com%2F%3Ftbpm%3Dt 来检查在 taobao.com 是否有登陆 登陆则跳回 http://pass.etao.com/add?... 进行登陆后在跳回首页,登陆状态为登陆 未登陆则依然跳回首页,登陆状态为未登陆 如今基本知道怎么去作了,或者有其它更好方法的?说出来你们讨论一下……


答案以下: 研究并看过sohu的,拿出来分享。

统一在 login.common.com?return=www.a.com 登陆,(带须要返回的地址) if 验证成功 return js,在login.common.com/success 加入返回的JS,并显示,而后跳回 return 参中带的值。

那么这段JS内容是什么样的呢? 就是经过JS的方式调用各个站点,生成各自的cookie。

目前 ucenter 也是采用这种方式。 登陆中心,应该要有一个相似应用列表这样的东西。

连接

willerce1.6k 2011年10月24日回答 0回复 joyqi · 2011年10月24日

我知道的有下面三种方法:

  1. 页面嵌套 JS 跨域请求, 就像康盛的 UCenter 产品同样;
  2. 让页面依次跳转不一样应用的域名来解决跨域问题;
  3. Google 同样的, 用户主动请求;

下面是详细:

  1. app1, app2, app3 挂接在 UC 上, 用户请求 app1 登陆, app1 程序在验证经过同时请求 UC 须要同步登陆的代码(以下), 打印到页面上.

<script type="text/javascript" src="http://app2/api/uc.php?time=132 4695020&code=f97bp%2FyiCrfFF%2B4lIndT1k3PoVk5%2BmVvNJMYiBzq7ssWE8FS smj7T3jujWyDpKpT2t8vO7o5M19FlzvNdihXMDWqvyoko9C3lkpG%2BQX57zL112gb GH%2FPwS9YD9A3%2BQVKNFSDzriFOqq9IFWJx6q4x%2Fk%2FMAltJygTiwRZ" reload="1"></script>

<script type="text/javascript" src="http://app3/api/uc.php?time=1324 695020&code=2b55qIaEphMxdvEYZJok8GEoDW%2BctvZeWS84LvaH8MHf8AzrRXiLD ZFIvS4cmUkXAGGeDnSVQ9rsu62iDnSAUSTEdSH2%2Bup5xZFvtgl9KRMEcOLLySih2w vNL%2BSjRQgqErT5kEK0878zxlhRQn0ypgxXgmoCY3zE87sy" reload="1"></script>

注意的是, uc.php 须要 p3p header

header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); 2. app1, app2, app3, 用户请求 app1 登陆, app1 程序在验证经过的时候让带着参数让浏览器跳到 app2.com (在输出页面的时候加上一段js, 代码相似下面), 而后再跳到 app3.com ... 依次种上 cookie 最后跳回 app1.com

<script type="text/javascript" reload="1">window.location.href=\'app1.com /loginAuth.phpcode=ctvZeWS84LvaH8MHf8AzrRXiLDZFIvS4cmUkXAGGeDnSVQ9rsu62i DnSAUSTEdSH2%2Bup5xZFvtgl9KRMEcOLLySih2wvNL%2BSjRQgqErT5kEK0878zxlhRQn0yp gxXgmoCY3zE87s'\';</script>

坏处是 - 在用户看起来, 页面会有好一下子的白屏! 不适合多个应用.

3 . Google 的方法, 坏处是用户得主动的点击登陆按钮, 无法作到无缝的同步登陆, 好处是适合多个应用;

哪个好, 得看什么要求, 若是不须要作到无缝的同步登陆的话, 确定是使用 Google 的方案!

google的这个办法应该是一个比较完整的流程了,可是仍是有些缺点,那就是在我没有访问youtube的时候登陆了google,它没有给我自动登陆到youtube,还须要你手动点击登陆。虽然不用输入密码啥的,但也有些麻烦。

其实能够作一个改进,就是你在youtube里挂一个google域的js,固然这个js其实是经过动态脚本输出的。咱们在脚本里先检查用户时候已经在google域里登陆过了,若是已经登陆,那么就动态输出让它在youtube域里也登陆的js。

这个好处虽然只省了一步,其实是把你在问题中的第一种方法写cookie的时间分散到访问各个子站去完成,可让用户几乎感受不到。

连接

joyqi6.2k 2011年10月04日回答 添加评论

相关文章
相关标签/搜索