php+ajax+P3P实现多域名跨域登陆

近期公司项目,须要实现A域名用户与B域名用户的同步登陆;
该同步登录需求需知足如下三个关键点:
1)A域名下登录的用户,跳转到B域名下时实现同步登录;
2)B域名下点击A域名下的退出连接,实现A域名与B域名的同时退出
3)用户直接访问B域名时,能够自动判断A域名下是否存在用户登陆,若是存在,则实现B域名下的用户同步登录。javascript

首先解决跨域的同步登录登出,有如下可行的解决思路:
1)两个域共享SESSION服务器,即统一的内存服务器,这样两个域下的SESSIONID会相同,会自动无缝实现同步登录登出;
但该解决方案须要额外的硬件投入,而且须要懂这方面部署的技术人员
2)经过url传递sessionid
3)经过P3P协议获取跨域的SESSIONphp

为解决该需求,我通过查询各类资料,并拟定了本身的一套解决方案,分享给你们,其要点以下:
1)当用户在A域名下登陆后,访问A域名下网站时,会ajax请求B域下的js脚本文件,写入B域COOKIE及SESSION,实现B域下登陆;
2)当用户在A域名下退出后,访问A域名下网站时,会ajax请求B域下的js脚本文件(同登陆参数不一样),清除B域COOKIE及SESSION,实现B域下登出;
3)当用户直接访问B域网页时,请求A域下脚本,判断A域下是否存在登陆,若是存在,则将COOKIE及SESSION赋值到当前域的网页中,经过ajax实现当前域html

COOKIE及SESSION的写入。java

我将baitianshi.cc设定为A域名;bstv.cc设定为B域名。jquery

如下是相关代码:ajax

############# baitianshi.cc ApiController.php #################api

 /* 
  * 根据当前域(baitianshi.cc)的cookie信息设置bstv域下的cookie及session
  * 若是为空,则清空处理
  * */
 function setckAction() {
  $clr = $this->_request->getParam("clr");
  $bts_user = ($clr) ? '' : urlencode($_COOKIE['bts_LOGGED_USER']);
  $this->view->assign("bts_user",$bts_user);
 }
 
 /* 
  * 提供给bstv域下,获取当前域(baitianshi.cc)的cookie及session
  * 以脚本变量返回给bstv浏览器端
  * */
 function getckAction() {
  header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
  echo 'var ck="'.$_COOKIE['bts_LOGGED_USER'].'";';
  echo 'var sess="'.$_SESSION['user']['uid'].'";';
  exit();
 }

############# baitianshi.cc index.php #################
##### 默认指定index.php为登陆返回的页面跨域

<script src="http://www.bstv.cc/api/setck?bts_user={$bts_user}"></script>

############# bstv.cc api.php #################浏览器

 /* 
  * 显示baitianshi.cc域下的cookie及SESSION
  * 赋值到js变量
  * js 经过ajax写入cookie和session:若是baitianshi.cc已退出,则bstv作退出处理
  * */
 function getbtsck() {
  include $this->template->getfile('api/getbtsck');
 }
 
 /* 
  * baitianshi.cc域下设置bstv域下的cookie及session
  * 若是为空,则清空处理
  * */
 function setck() {
  header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
  
  $bts_user = trim($_GET['bts_user']);
  if(!empty($bts_user)) {
   setcookie("bts_LOGGED_USER", urldecode($bts_user), time()+3600*24*365, "/", ".bstv.cc");
   $this->cookieLoginLocal(urldecode($bts_user));
  } else {
   setcookie("bts_LOGGED_USER", $bts_user, '-1', "/", ".bstv.cc");
   unset($_SESSION['uid']);
  }
 }
 
 function setsession() {
  $bts_user = trim($_POST['bts_user']);
  if(!empty($bts_user) && empty($_SESSION['uid'])) {
   setcookie("bts_LOGGED_USER", urldecode($bts_user), time()+3600*24*365, "/", ".bstv.cc");
   $this->cookieLoginLocal(urldecode($bts_user));
  } else {
   echo 'uuunset';
   setcookie("bts_LOGGED_USER", $bts_user, '-1', "/", ".bstv.cc");
   //unset($_SESSION['uid']);
  }
 }
 
 function cookieLoginLocal($cookieId){
  $cookieId = explode( '.', base64_decode($cookieId) );
  if ($cookieId[0] !== 'baitianshi' || empty($cookieId[1])) {
   return false;
  } else {
   return $this->loginLocal($cookieId[1],false,1);
  }
 }
 
 function loginLocal($uid,$password=false,$isuid=0) {
  $_SESSION['uid'] = $uid;
  return 1;
 }


############# bstv.cc getbtsck.html #################服务器

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
 <title>同步登录</title>
 <script src="http://p.bstv.cc/js/jquery-1.8.1.min.js" type="text/javascript"></script>
    <script src="http://www.baitianshi.cc/api/getck"></script>
 <script language="javascript">
 function setck(bts_user) {
  $.post("/api/setsession",{bts_user:bts_user},function(re){ });}
  setck(ck);
    </script>
</head>
<body></body>
</html>

该方案尚存在的不足: 当用户直接访问B域时,须要加载一次该页面后,才能判断是否在A域登陆,并写入当前域(B域)的SESSION

相关文章
相关标签/搜索