zoukankan      html  css  js  c++  java
  • php实现SESSION跨域

    稍微大一点的网站,通常都会有不只一个服务器,每个服务器运行着不同的功能模块或者不同的子系统,他们使用不同的二级域名,比如www.a.com、i.a.com、bbs.a.com。而一个整体性强的网站,用户系统是统一的,即一套用户名、密码在整个网站的各个子系统中都是可以登录使用的。各个服务器共享用户数据是比较容易实现的,只需要在后端放个数据库服务器,各个服务器通过统一接口对用户数据进行访问即可。但还存在一个问题,就是用户在i.a.com登录之后,进入www.a.com时,仍然需要重新登录,基本的通行证的问题,映射到技术上,其实就是各个服务器之间如何实现共享 SESSION 数据的问题。

    为了解决这个问题,我们采用将 SESSION 的数据保存数据库的方式。关于PHP SESSION的扫盲这里就不在累赘。在默认情况下,各个服务器会各自分别对同一个客户端产生 SESSION ID,如对于同一个用户浏览器,www.a.com系统产生的 SESSION ID 是a0211e9de3192ba6c22992d27a1b6a0a,而i.a.com生成的则是277003f262f0c366946a86a28ba431d8。另外,PHP 的 SESSION 数据都是分别保存在本服务器的文件系统中。

    想要共享 SESSION 数据,那就必须实现两个目标:www.a.com和i.a.com所产生的SESSION ID相同,并且可通过同一个 COOKIE 进行传递,也就是说各个服务器必须可以读取同一个名为 PHPSESSID 的 COOKIE;另一个是 SESSION 数据必须存放在一个各个系统都能访问到的地方。简单地说就是多服务器共享客户端的 SESSION ID,同时还必须共享服务器端的 SESSION 数据。

    第一个目标的实现其实很简单,只需要对 COOKIE 的域(domain)进行特殊地设置即可,默认情况下,COOKIE 的域是当前服务器的域名/IP 地址,而域不同的话,各个服务器所设置的 COOKIE 是不能相互访问的,如 www.a.com 的服务器是不能读写 www.b.com 服务器设置的 COOKIE 的。这里我们所说的同一网站的服务器有其特殊性,那就是他们同属于同一个一级域,如:www.a.com 和 i.a.com 都属于域 .a.com,那么我们就可以设置 COOKIE 的域为 .a.com,这样 www.a.com、i.aaa.com 等等都可以访问此 COOKIE。PHP 代码中的设置方法如下:

    ini_set('session.cookie_domain', '.a.com');
    

      

    这样各个系统共享同一客户端 SESSION ID 的目的就达到了,下面就是共享SESSION数据,我们就将SESSION数据放在数据库中,首先建立数据库表:

    CREATE TABLE sessions (
     session_id varchar(32) NOT NULL,
     session_last_access int(10) unsigned,
     session_data text,
     PRIMARY KEY (session_id)
    

      

    session_id为主键,保存SESSION ID ,session_last_access是SESSION最后更新时间,session_data是SESSION数据。
    PHP 提供了session_set_save_handle() 函数,可以用此函数自定义 SESSION 的处理过程,当然首先要先将 session.save_handler 改成 user,可在 PHP 中进行设置:
    接下来着重讲一下 session_set_save_handle() 函数,此函数有六个参数:
    session_set_save_handler ( string open, string close, string read, string write, string destroy, string gc )
    各个参数为各项操作的函数名,这些操作依次是:打开、关闭、读取、写入、销毁、垃圾回收。PHP 手册中有详细的例子,详细代码如下:

    $gb_DBHOSTname = "127.0.0.1"; //主机的名称或是IP地址
    
    $gb_DBname = "dbname"; //数据库名称
    
    $gb_DBuser = "username"; //数据库用户名称
    
    $gb_DBpass = "pwd"; //数据库密码
    
    $gb_COOKIE_DOMAIN = '.a.com';
    
    $SESS_DBH = "";
    
    $SESS_LIFE = get_cfg_var("session.gc_maxlifetime"); //得到session的最大有效期。
    
     session_id(); //不使用 GET/POST 变量方式
    ini_set('session.use_trans_sid', 0); //设置垃圾回收最大生存时间
    ini_set('session.gc_maxlifetime', 13600); //使用 COOKIE 保存 SESSION ID 的方式
    ini_set('session.use_cookies', 1);
    ini_set('session.cookie_path', '/'); //多主机共享保存 SESSION ID 的 COOKIE
    ini_set("session.cookie_domain", $gb_COOKIE_DOMAIN);
    //将 session.save_handler 设置为 user,而不是默认的 files session_module_name('user');
    function sess_open($save_path, $session_name) {
        global $gb_DBHOSTname, $gb_DBname, $gb_DBuser, $gb_DBpass, $SESS_DBH;
        if (!$SESS_DBH = mysql_pconnect($gb_DBHOSTname, $gb_DBuser, $gb_DBpass)) {
            die('MySQL Error');
        }
        mysql_query("SET character_set_connection=utf8, character_set_results=utf8, character_set_client=binary", $SESS_DBH);
        if (!mysql_select_db($gb_DBname, $SESS_DBH)) {
            die('MySQL Error');
        }
        return true;
    }
    function sess_close() {
        global $SESS_DBH;
        //$SESS_DBH->Close();
        return true;
    }
    
    function sess_read($key) {
        global $SESS_DBH, $SESS_LIFE;
    //      var_dump($SESS_DBH);
        $qry = "select session_data from sessions where session_id = '$key' ";
        $qid = mysql_query($qry, $SESS_DBH);
    //      var_dump($qid);
        if (list ($value) = mysql_fetch_row($qid)) {
            return $value;
        }
        return false;
    }
    function sess_write($key, $val) {
        global $SESS_DBH, $SESS_LIFE;
        $session_last_access = time();
        $value = $val;
        $qry = "insert into  sessions values('$key',$session_last_access,'$value')";
        $qid = mysql_query($qry, $SESS_DBH);
        if (!$qid) {
            $qry = "update sessions set session_last_access=$session_last_access, session_data='$value' where session_id='$key' ";
            $qid = mysql_query($qry, $SESS_DBH);
        }
        return $qid;
    }
    
    function sess_destroy($key) {
        global $SESS_DBH;
        $qry = "delete from sessions where session_id = '$key'";
        $qid = mysql_query($qry, $SESS_DBH);
        return $qid;
    }
    
    function sess_gc($maxlifetime) {
        global $SESS_DBH;
        $old = time() - $maxlifetime;
        $old = mysql_real_escape_string($old);
        $qry = "delete from sessions where session_last_access < " . $old;
        $qid = mysql_query($qry, $SESS_DBH);
        return mysql_affected_rows($SESS_DBH);
    }
    session_module_name();
    session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write","sess_destroy", "sess_gc");
    session_start();
    

      

    01 $gb_DBHOSTname "127.0.0.1"//主机的名称或是IP地址
    02 $gb_DBname "dbname"//数据库名称
    03 $gb_DBuser "username"//数据库用户名称
    04 $gb_DBpass "pwd"//数据库密码
    05 $gb_COOKIE_DOMAIN '.a.com';
    06 $SESS_DBH "";
    07 $SESS_LIFE = get_cfg_var("session.gc_maxlifetime"); //得到session的最大有效期。
    08  session_id(); //不使用 GET/POST 变量方式
    09 ini_set('session.use_trans_sid', 0); //设置垃圾回收最大生存时间
    10 ini_set('session.gc_maxlifetime', 13600); //使用 COOKIE 保存 SESSION ID 的方式
    11 ini_set('session.use_cookies', 1);
    12 ini_set('session.cookie_path''/'); //多主机共享保存 SESSION ID 的 COOKIE
    13 ini_set("session.cookie_domain"$gb_COOKIE_DOMAIN);
    14 //将 session.save_handler 设置为 user,而不是默认的 files session_module_name('user');
    15 function sess_open($save_path$session_name) {
    16     global $gb_DBHOSTname$gb_DBname$gb_DBuser$gb_DBpass$SESS_DBH;
    17     if (!$SESS_DBH = mysql_pconnect($gb_DBHOSTname$gb_DBuser$gb_DBpass)) {
    18         die('MySQL Error');
    19     }
    20     mysql_query("SET character_set_connection=utf8, character_set_results=utf8, character_set_client=binary"$SESS_DBH);
    21     if (!mysql_select_db($gb_DBname$SESS_DBH)) {
    22         die('MySQL Error');
    23     }
    24     return true;
    25 }
    26  
    27 function sess_close() {
    28     global $SESS_DBH;
    29     //$SESS_DBH->Close();
    30     return true;
    31 }
    32  
    33 function sess_read($key) {
    34     global $SESS_DBH$SESS_LIFE;
    35 //      var_dump($SESS_DBH);
    36     $qry "select session_data from sessions where session_id = '$key' ";
    37     $qid = mysql_query($qry$SESS_DBH);
    38 //      var_dump($qid);
    39     if (list ($value) = mysql_fetch_row($qid)) {
    40         return $value;
    41     }
    42     return false;
    43 }
    44  
    45 function sess_write($key$val) {
    46     global $SESS_DBH$SESS_LIFE;
    47     $session_last_access = time();
    48     $value $val;
    49     $qry "insert into  sessions values('$key',$session_last_access,'$value')";
    50     $qid = mysql_query($qry$SESS_DBH);
    51     if (!$qid) {
    52         $qry "update sessions set session_last_access=$session_last_access, session_data='$value' where session_id='$key' ";
    53         $qid = mysql_query($qry$SESS_DBH);
    54     }
    55     return $qid;
    56 }
    57  
    58 function sess_destroy($key) {
    59     global $SESS_DBH;
    60     $qry "delete from sessions where session_id = '$key'";
    61     $qid = mysql_query($qry$SESS_DBH);
    62     return $qid;
    63 }
    64  
    65 function sess_gc($maxlifetime) {
    66     global $SESS_DBH;
    67     $old = time() - $maxlifetime;
    68     $old = mysql_real_escape_string($old);
    69     $qry "delete from sessions where session_last_access < " $old;
    70     $qid = mysql_query($qry$SESS_DBH);
    71     return mysql_affected_rows($SESS_DBH);
    72 }
    73 session_module_name();
    74 session_set_save_handler("sess_open""sess_close""sess_read""sess_write","sess_destroy""sess_gc");
    75 session_start();
  • 相关阅读:
    2015腾讯暑期实习笔试题目
    二叉树的优点和缺点
    pandas对象保存到mysql出错提示“BLOB/TEXT column used in key specification without a key length”解决办法
    事务的隔离机制
    Flink Sink定制开发
    Presto实现定时从配置文件读取配置
    LDAP与Sentry API使用
    Presto压测报告
    PrestoSPI安全扩展
    项目重构总结
  • 原文地址:https://www.cnblogs.com/mracale/p/6688722.html
Copyright © 2011-2022 走看看