首页 > php代码 > php+ajax实现多域名跨域登录例子(基于P3P)

php+ajax实现多域名跨域登录例子(基于P3P)

在以前如果我们要实现php+ajax实现多域名跨域登录的话很多朋友都碰到无法正常跨域登录问题,下面我来给大家解决跨域名登录问题,有需要的参考。

该同步登陆需求需满足以下三个关键点:

1)A域名下登陆的用户,跳转到B域名下时实现同步登陆;

2)B域名下点击A域名下的退出链接,实现A域名与B域名的同时退出

3)用户直接访问B域名时,可以自动判断A域名下是否存在用户登录,如果存在,则实现B域名下的用户同步登陆。

首先解决跨域的同步登陆登出,有以下可行的解决思路:

1)两个域共享SESSION服务器,即统一的内存服务器,这样两个域下的SESSIONID会相同,会自动无缝实现同步登陆登出;

但该解决方案需要额外的硬件投入,并且需要懂这方面部署的技术人员

2)通过url传递sessionid

3)通过P3P协议获取跨域的SESSION

为解决该需求,我经过查询各种资料,并拟定了自己的一套解决方案,分享给大家,其要点如下:

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实现当前域

COOKIE及SESSION的写入。

我将a域名设定为A域名;B域名设定为B域名。

以下是相关代码:

<?php
//############a域名ApiController.php #################
/*
 * 根据当前域(a域名)的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域下,获取当前域(a域名)的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();
}
?>

#############a域名index.php #################

##### 默认指定index.php为登录返回的页面

<script src="http://www.B域名/api/setck?bts_user={$bts_user}"></script>

############# B域名 api.php #################

<?php
/*
 * 显示a域名域下的cookie及SESSION
 * 赋值到js变量
 * js 通过ajax写入cookie和session:如果a域名已退出,则bstv做退出处理
 * */
function getbtsck() {
    include $this->template->getfile('api/getbtsck');
}
/*
 * a域名域下设置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, "/", ".B域名");
        $this->cookieLoginLocal(urldecode($bts_user));
    } else {
        setcookie("bts_LOGGED_USER", $bts_user, '-1', "/", ".B域名");
        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, "/", ".B域名");
        $this->cookieLoginLocal(urldecode($bts_user));
    } else {
        echo 'uuunset';
        setcookie("bts_LOGGED_USER", $bts_user, '-1', "/", ".B域名");
        //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;
}
?>

############# B域名 getbtsck.html #################

<!DOCTYPE html>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
 <title>同步登陆</title>
 <script src="/js/jquery-1.8.1.min.js" type="text/javascript"></script>
    <script src="/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


本文地址:http://www.phprm.com/code/62944.html

转载随意,但请附上文章地址:-)

标签:include explode request

相关文章

发表留言