php处理session跨域几种的方案

文章来源:365jz.com     点击数:81    更新时间:2017-08-30 12:43   参与评论
有N个网站,假设域名如下a.test.com,b.test.com,c.test.com,d.test.com......N个网站都存在session['e'],现在有一需求,在网站b中执行操作,通知a清除session['e'],a收到命令后,再通知其他服务器清除session['e'],我不想用ajax做,因为涉及到不能用js的情况,我想要的是后台之间的交互,有什么好方法

前面谈过session相关配置,在开发的时候,常需要跨域共用session的是登录模块,我相信很多开发的朋友的都遇到过,只需要一个地方登录,相关联的网站也是处于登录状态。两种情况:一种9streets.cn和a.9streets.cn之间,另一种是a.com b.com之间,这几天总结了一下处理方法。
无论是一二级域名,和不同域名下的跨域,无非要达到两点:
1.客户端访问同一个sessionId
2.所有域名对应的服务器访问的session的数据的位置必须一致。
1.访问共同的sessionId,把当前的sessionId写进cookie里面cookie在不同域名下是不能访问的,我们需要在访问在后台设置用户在登录的时候,把需要共用的登录信息的域名,如果是在1,2级域名下,直接把 cookie设置为所属主域名,例如:setcookie("session_id",session_id(),time()+3600*24*365*10,"/",".a.com");
也许你会问:如果是在不同的域名呢?采用P3P技术简单解决,实现原理,在访问网站x.com的时候,y.com程序触发y.com文件的写入 sessionid值,sessionid值便可以获取,然后把seesion值存入数据库,取相同的sessionid值便可。这就要求y.com里面的程序文件必需能跨域访问,默认情况下,浏览器是不能跨域设置cookie的,加上p3p头后才行。在对应PHP文件加上:header(‘P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"’);

2.session数据存储位置一致的实现方法
session该数据默认情况下是存放在服务器的tmp文件下的,是以文件形式存在,而非存储在服务器的内存中,在这里我们得修改为所有域下都能访问的方式。网上介绍了数据库存储,文件形式存储,内存存储, 如果用数据库存储session数据,网站的访问量很大的话,SESSION 的读写会频繁地对数据库进行操作,效率就会明显降低,可以考虑存在内存服务器来实现,下面的session.rar里面介绍的是数据库存session的实例。
常用跨域共用session的是登录模块,我相信很多开发的朋友的都遇到过,只需要一个地方登录,相关联的网站也是处于登录状态。两种情况:一种9streets.cn和a.9streets.cn之间,另一种是a.com b.com之间
方式一: 在一,二级域名下调用如下代码:
  

<?php  
    include("DBsession.php");  
    $_SESSION['usssser_oke'] = 'xxssssss';  
    $_SESSION['user_oke'] = 'xxsss';    
?> 


DBsession.php

<?php  
/**
/**  直接引用api QQ登录的session写法,配置相关配置才行哈
* 设置session配置 
*/  
/**
* CREATE TABLE `tbl_session` (
*     `session_id` varchar(255) binary NOT NULL default '',
*     `session_expires` int(10) unsigned NOT NULL default '0',
*     `session_data` text,
*     PRIMARY KEY  (`session_id`)
*    ) ENGINE=MyISAM;
*/  
class Session   
{  
    //mySQL的主机地址  
    const db_host = "localhost"; //需要第三方指定ip地址   
    //数据库用户名  
    const db_user = "root";   //需要第三方指定自己的用户名  
    //数据库密码  
    const db_pwd = ""; //需要第三方指定自己的库据库密码  
    //数据库  
    const db_name = "thinkphp";      //需要第三方指定数据库  
    //数据库表  
    const db_table = "tbl_session"; //需要第三方指定数据表  
    //mysql-handle  
    private $db_handle;  
    //session-lifetime  
    private $lifeTime;  
    function open($savePath, $sessName)   
    {  
        // get session-lifetime  
        $this--->lifeTime = get_cfg_var("session.gc_maxlifetime");  
        // open database-connection  
        $db_handle = @mysql_connect(self::db_host, self::db_user, self::db_pwd);  
        $dbSel = @mysql_select_db(self::db_name, $db_handle);  
        // return success  
        if(!$db_handle || !$dbSel)  
            return false;  
        $this->db_handle = $db_handle;  
        return true;  
    }  
    function close()   
    {  
        $this->gc(ini_get('session.gc_maxlifetime'));  
        // close database-connection  
        return @mysql_close($this->db_handle);  
    }  
    function read($sessID)   
    {  
        // fetch session-data  
        $res = @mysql_query("SELECT session_data AS d FROM ".self::db_table." 
            WHERE session_id = '$sessID'
            AND session_expires > ".time(), $this->db_handle);  
        // return data or an empty string at failure  
        if($row = @mysql_fetch_assoc($res))  
            return $row['d'];  
        return "";  
    }  
    function write($sessID, $sessData)   
    {  
        // new session-expire-time  
        $newExp = time() + $this->lifeTime;  
        // is a session with this id in the database?  
        $res = @mysql_query("SELECT * FROM ".self::db_table." 
            WHERE session_id = '$sessID'", $this->db_handle);  
        // if yes,  
        if(@mysql_num_rows($res))   
        {  
            // ...update session-data  
            @mysql_query("UPDATE ".self::db_table." 
                SET session_expires = '$newExp',
                session_data = '$sessData'
                WHERE session_id = '$sessID'", $this->db_handle);  
            // if something happened, return true  
            if(@mysql_affected_rows($this->db_handle))  
                return true;  
        }  
        else // if no session-data was found,  
        {  
            // create a new row  
            @mysql_query("INSERT INTO ".self::db_table." (
                session_id,
                session_expires,
                session_data)
                VALUES(
                    '$sessID',
                    '$newExp',
                    '$sessData')", $this->db_handle);  
            // if row was created, return true  
            if(@mysql_affected_rows($this->db_handle))  
                return true;  
        }  
        // an unknown error occured  
        return false;  
    }  
    function destroy($sessID)   
    {  
        // delete session-data  
        @mysql_query("DELETE FROM ".self::db_table." WHERE session_id = '$sessID'", $this->db_handle);  
        // if session was deleted, return true,  
        if(@mysql_affected_rows($this->db_handle))  
            return true;  
        // ...else return false  
        return false;  
    }  
    function gc($sessMaxLifeTime)   
    {  
        // delete old sessions  
        @mysql_query("DELETE FROM ".self::db_table." WHERE session_expires < ".time(), $this->db_handle);  
        // return affected rows  
        return @mysql_affected_rows($this->db_handle);  
    }  
}  
/**
* 指定session有效的域名
* ini_set("session.cookie_domain", ".domain.com");
* .domain.com是站点的主域名,请注意前面个有一个'.'
*/  
define("MAIN_DOMAIN", ".ichezone.com");   //设置主域名  
/**
* 不同子域名下共享session信息
* COOKIE_DOMAIN = false 禁止该功能
* COOKIE_DOMAIN = true  启用该功能
* 默认禁止
* 开启前提需要定义MAIN_DOMAIN常量
*/  
define("COOKIE_DOMAIN", true);   
if (defined("COOKIE_DOMAIN") && COOKIE_DOMAIN)  
{  
    if (defined("MAIN_DOMAIN"))  
        @ini_set("session.cookie_domain", MAIN_DOMAIN);  
}  
/**
* 同一个主域名,不同服务器之间共享session信息
* USER_SESSION = false 禁用该功能
* USER_SESSION = true  启用该功能
* 默认禁止
* 开启前提需要建立mysql数据表
*/  
ini_set('session.name', 'phpsessid');//设置色session id的名字  
define("USER_SESSION", true);  
if (defined("USER_SESSION") && USER_SESSION)  
{  
    @ini_set("session.save_handler", "user");  
    $session = new Session;  
    @session_module_name("user");  
    @session_set_save_handler(  
        array(&$session, "open"),  
        array(&$session, "close"),  
        array(&$session, "read"),  
        array(&$session, "write"),  
        array(&$session, "destroy"),  
        array(&$session, "gc"));  
}  
//@ini_set("session.save_path", dirname(__file__)."/tmp");  
//@session_id("demo");  
//ini_set("session.save_path",dirname(__file__)."/tmp");  
session_start();
include("DBsession.php");  
$_SESSION['usssser_oke'] = 'xxssssss';  
$_SESSION['user_oke'] = 'xxsss';   
?> 

方式二: 

<?php
ini_set('session.name', 'sid');//设置色session id的名字
ini_set('session.use_trans_sid', 0);//不使用 GET/POST 变量方式
ini_set('session.use_cookies', 1);//使用 COOKIE 保存 SESSION ID 的方式
ini_set('session.cookie_path', '/');
ini_set('session.cookie_domain', '.ichezone.com');//多主机共享保存 SESSION ID 的 COOKIE,注意此处域名为一级域名
session_start();
$_SESSION['usssser_oke'] = 'xxssssss';
$_SESSION['user_oke'] = 'xxsss';  
?>

方式三:
一级域名:

session_start();
setcookie("session_id",session_id(),time()+3600*24*365*10,"/",".ichezone.com");
$_SESSION['user_name'] = '梁山良民';

二级域名:

session_id($_COOKIE['session_id']);
session_start();
$_SESSION['user_sssme'] = 222222;

方式四:
一级域名:

ini_set("session.cookie_domain",'.ichezone.com');//注:该参数必须在sesson_start()之上,否则将不会生效
session_start();
$_SESSION['user_name'] = '梁山www良民';

二级域名:

ini_set("session.cookie_domain",'.ichezone.com');//注:该参数必须在sesson_start()之上,否则将不会生效
session_start();
$_SESSION['user_nassse'] = '梁山www良民'; 

方式五:采用的p3p技术,实现原理,在访问网站x.com的时候,y.com程序触发y.com文件的写入sessionid值,sessionid值便可以获取,然后把seesion值存入数据库,取相同的sessionid值便可。这就要求y.com里面的程序文件必需能跨域访问,默认情况下,浏览器是不能跨域设置cookie的,加上p3p头后才行。在对应php文件加上:
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); 

网上博文:
    127.0.0.1        www.a.com
    127.0.0.1        www.b.com
    首先:创建 a_setcookie.php 文件,内容如下:

    <?php
    header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
    setcookie("test", $_GET['id'], time()+3600, "/", ".a.com");
    ?>

    然后:创建 a_getcookie.php 文件,内容如下:

    <?php
    var_dump($_COOKIE);
    ?>

    最后:创建 b_setcookie.php 文件,内容如下:
<script src="http://www.a.com/a_setcookie.php?id=www.b.com"></script>
    ----------------------------
三个文件创建完毕后,我们通过浏览器依次访问:

http://www.b.com/b_setcookie.php


http://www.a.com/a_getcookie.php

我们会发现,在访问b.com域的时候,我们并没有在a.com域设置上cookie值。去掉重新访问两文件设置成功

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (81人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------