SSO单点登录在web上的关键点 cookie跨域
概述
其实WEB单点登录的原理挺简单的,抛开那些复杂的概念,简单来讲讲如何实现一个最基本的单点登录
-
首先需要有两个程序 例如:http://www.site-a.com 我们简称A http://www.stie-b.com 我们简称B
-
A 和 B 在登录认证逻辑上(通常使用的是session技术)将登录验证数据单独存在第三方的存储结构中 例如 数据库或者内存缓存服务器 关于这方面技术请自行去寻找相关资料
-
用户在登录A站点的时候,创建登录信息,并存起来 然后留出一个接口 可以讲一个已经登录的标识传递给B站点页面上
-
用户在访问B的时候 javascript从B页面上获取到A的登录标识,将这个标识发动到B的程序后端查询用户是否在A上具有登录信息,如果存在则登录确认,直接跳过B站点的登录逻辑
那么在整个四步当中,其实最麻烦的是4,因为A和B的域名不同,在浏览器段往往不允许跨域传递数据
解决方案
利用B页面上的iframe分帧来从B站点页面跳转到A站点接口页面上,通过window.name进行跨域通信
具体实施
A:
1 <?php 2 //index.php 创建需要跨域的信息 3 setCookie('key','跨域的cookie内容'); 4 5 6 <?php 7 //sso.php 接口 8 echo '<script>'; 9 echo 'window.name ='.$_COOKIE['key']; 10 echo '</script>';
B站点页面:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 </head> 6 <body> 7 <script type="text/javascript"> 8 function domainData(url, fn) 9 { 10 var isFirst = true; 11 var iframe = document.createElement('iframe'); 12 iframe.style.display = 'none'; 13 var loadfn = function(){ 14 if(isFirst){ 15 iframe.contentWindow.location = 'http://www.site-b.com/null.html'; 16 isFirst = false; 17 } else { 18 fn(iframe.contentWindow.name); 19 iframe.contentWindow.document.write(''); 20 iframe.contentWindow.close(); 21 document.body.removeChild(iframe); 22 iframe.src = ''; 23 iframe = null; 24 } 25 }; 26 iframe.src = url; 27 if(iframe.attachEvent){ 28 iframe.attachEvent('onload', loadfn); 29 } else { 30 iframe.onload = loadfn; 31 } 32 33 document.body.appendChild(iframe); 34 } 35 </script> 36 37 <script type="text/javascript"> 38 domainData('http://www.site-a.com/sso.php', function(data){ 39 alert(data); 40 }); 41 </script> 42 </body> 43 </html>
同时要注意代码当中的http://www.site-b.com/null.html 要创建一个这样的空白页面 保证iframe的访问顺序是 B的null → A的sso.php 现在先访问A的index.php创建cookie,然后再访问B的页面就可以获取到cookie数据了,至于具体怎么实现后端逻辑,不在本文探讨之内