Heim > Artikel > Backend-Entwicklung > javascript - 如何实现 [ 跨域单点登录 ] ?
管理用户网站
http://accounts.com
http://accounts.com/login
http://accounts.com/logout
http://app1.com
http://app2.com
http://accounts.com/login
进行登录http://app1.com/callback?token=xxxx
来验证登录https://accounts.google.com/ServiceLoginAuth
验证用户名密码https://accounts.google.com/CheckCookie
检查是否有浏览过其它应用,比如说 youtube,这时就再次跳转到 https://accounts.youtube.com/accounts/SetSID
进行登录https://accounts.google.com/ServiceLoginAuth
,但是不用任何输入直接跳回 yutube 首页http://jump.taobao.com/jump?target=http%3A%2F%2Fwww.etao.com%2F%3Ftbpm%3Dt
来检查在 taobao.com 是否有登录http://pass.etao.com/add?...
进行登录后在跳回首页,登录状态为登录管理用户网站
http://accounts.com
http://accounts.com/login
http://accounts.com/logout
http://app1.com
http://app2.com
http://accounts.com/login
进行登录http://app1.com/callback?token=xxxx
来验证登录https://accounts.google.com/ServiceLoginAuth
验证用户名密码https://accounts.google.com/CheckCookie
检查是否有浏览过其它应用,比如说 youtube,这时就再次跳转到 https://accounts.youtube.com/accounts/SetSID
进行登录https://accounts.google.com/ServiceLoginAuth
,但是不用任何输入直接跳回 yutube 首页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 也是采用这种方式。 登录中心,应该要有一个类似应用列表这样的东西。
google的这个办法应该是一个比较完整的流程了,但是还是有些缺点,那就是在我没有访问youtube的时候登录了google,它没有给我自动登录到youtube,还需要你手动点击登录。虽然不用输入密码啥的,但也有些麻烦。
其实可以做一个改进,就是你在youtube里挂一个google域的js,当然这个js实际上是通过动态脚本输出的。我们在脚本里先检查用户时候已经在google域里登录过了,如果已经登录,那么就动态输出让它在youtube域里也登录的js。
这个好处虽然只省了一步,实际上是把你在问题中的第一种方法写cookie的时间分散到访问各个子站去完成,可以让用户几乎感觉不到。
我知道的有下面三种方法:
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%0A4695020&code=f97bp%2FyiCrfFF%2B4lIndT1k3PoVk5%2BmVvNJMYiBzq7ssWE8FS%0Asmj7T3jujWyDpKpT2t8vO7o5M19FlzvNdihXMDWqvyoko9C3lkpG%2BQX57zL112gb%0AGH%2FPwS9YD9A3%2BQVKNFSDzriFOqq9IFWJx6q4x%2Fk%2FMAltJygTiwRZ" reload="1"></script> <script type="text/javascript" src="http://app3/api/uc.php?time=1324%0A695020&code=2b55qIaEphMxdvEYZJok8GEoDW%2BctvZeWS84LvaH8MHf8AzrRXiLD%0AZFIvS4cmUkXAGGeDnSVQ9rsu62iDnSAUSTEdSH2%2Bup5xZFvtgl9KRMEcOLLySih2w%0AvNL%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 的方案!
app2.com 同样带上 ?token=xxx 不就好了, 如果是从 app1.com 的 link 跳转过去
我有一个不太有“对称完美”的解决办法,当app多的时候可能比较麻烦,但也算一个办法:
在app1.com的callback页面最后,加上script标签
<script src="http://app2.com/callback=<?php%20echo%20%24token%20?>" ...><p>这样可以让app2也登陆,不过你也看得出来,如果app比较多的时候,你的callback页面都得提到其他的app的callback地址,我说的麻烦就是指这个 <p class="answer fmt" data-id="1020000000097263"> <p>最简单的方法就是共用sessionid的方式<br /> 登陆完成后将sessionid用跳转或者js的方式传到个子站点,将原来的sessionid改为统一的sessionid<br /> 不过这样的缺点是session必须在同一部服务器,或者使用分布式的session存储如memcache,而且站点多的话登陆的时间会相应延长,但对于小站点是个简单的解决方式。 <p class="answer fmt" data-id="1020000000645329"> <p>http://www.codeproject.com/Articles/106439/Single-Sign-On-SSO-for-cross-domain-ASP-NET-applic <p>这个应该比较全 <p class="answer fmt" data-id="1020000004390411"> <p>如果是web而不是app,iframe是最简单最好维护的办法https://www.zhihu.com/question/19779937/answer/16503799<br>如果用app,<img / alt="javascript - 如何实现 [ 跨域单点登录 ] ?" >代替就可以了。<br>土一点,但真的很简单。 <p class="answer fmt" data-id="1020000002447135"> <p>通过识别cookie或者参考cas <p>php技术讨论群 323899029 </script>