博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP中利用COOKIE与SESSION联合实现SESSION跨域
阅读量:6892 次
发布时间:2019-06-27

本文共 3815 字,大约阅读时间需要 12 分钟。

  hot3.png

大家都知道是不可以的,也就是说: a.demo.com这个域的可执行文件不可以访问到b.demo.com的SESSION,这个是SESSION的特性,同样也是出于安全角度才这样的.

在一般情况下,一个网站只有一个域名,www.demo.com,但是也有些网站架构是由多个子域名组建的.所以就需要SESSION可以跨子域被 访问到,这样才可以实现用户的跨域登录.就是说客户在A下登录的,同样B也同时登录了,不需要用户再次登录,同时也实现了参数的跨域传递.当然不可跨域的 SESSION本身已经可以帮助我们做很多事情了,那么跨域后的SESSION呢.读到这里是否很激动人心,当然你也可能是正在为SESSION跨域而发 愁而找到这篇文章的,同样也祝贺你.我们长话断说了,开始Ioopen的话题:与SESSION联用实现SESSION跨域.

首先描述下我的思路,COOKIE可以指定域名,也就是说它可以跨域子域,例如:

setcookie(’name’,’Ioopen’,time()+3600*24,’/’,’demo.com’)

,那么a.demo.com,b.demo.com都可以访问到$_COOKIE['name'],值也均为’Ioopen’.同 理,SESSION ID也可以设置成这个域名,那么a.demo.com和b.demo.com都可以得到同一个SESSION ID,那么我们的目的也就达到了.因为知道了同一个SESSION ID就可以访问到这个SESSION中的值了.SESSION有多种方式存储,文件\数据库\内存等,我们采用数据库存储,因为如果 a.demo.com,b.demo.com不在同一台服务器上,那么内存和文件的存储方式就很难实现跨域了,至于到底又没有方法,Ioopen还没有试 过.

首先在数据库中创建一张SESSION表:

CREATE TABLE `sessions` (`sid` varchar(32) NOT NULL default ”,`expiry` int(20) unsigned NOT NULL default ’0′,`value` text NOT NULL,PRIMARY KEY (`sid`),KEY `expiry` (`expiry`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;

然后写一个类,这个类用于读取\插入\更新\删除以及垃圾回收SESSION

class session{private $db;function __construct($db){$this->db=$db;}public function open($save_path,$session_name){return true;}public function close(){$this->db=null;return true;}public function read($sid){$rs=$this->db->query(“select * from sessions where sid=’”.$sid.”‘”);foreach ($rs as $row){return $row['value'];}return null;}public function write($sid,$value){if(is_null($oldvalue=$this->read($sid))){//insertreturn $this->db->query(”insert into sessions (sid,expiry,value)values(’”.$sid.”‘,’”.time().”‘,’”.$value.”‘)”);}else{//updatereturn $this->db->query(”update sessions set expiry=’”.time().”‘,value=’”.$value.”‘ where sid=’”.$sid.”‘”);}}public function destroy($sid){return $this->db->query(”delete from sessions where sid=’”.$sid.”‘”);}public function gc($max_life_time){return $this->db->query(’delete from sessions where expiry+’.$max_life_time.’<’.time());}}

Ioopen来解释下这个类:

private $db;

类的DATABASE属性.

function __construct($db)

类的构造函数,在声明类时,可以直接传递DB属性到类中,当然如果还不明白可以先GOOGLE一下”PHP 类 construct 方法”;

public function open($save_path,$session_name) //session打开,没有什么花头,直接返回TRUE;public function close() //session关闭,同理open,但注意要关闭DB连接;public function read($sid) //session读取,传值SID,在数据表中将这个SID的VALUE作为返回值返回;public function write($sid,$value)// session的写入与更新,这个你会有疑问,为什么set expiry=’”.time().”‘,稍后答案在清空过期

SESSION GC方法中便会揭晓;

public function destroy($sid) //session的销毁,很简单,就是把数据表中等于这个SID的数据删除掉;public function gc($max_life_time) //清空过期session,把超过max_life_time的session都销毁掉,也就是session的创建时间加上最大生存时间小于现在时间( expiry+’.$max_life_time.’<’.time())的session数据删除掉,这下你会明白为什么在写入和更新session的方法中为什么写当前时间了吧,当然这个写法不是绝对的,随个人意愿只要你的SQL写正确了,也就可以了.

好我们接着来看更重要的部分:

上面的类中需要一个数据库链接属性,所以声明对象的时候需要这样:

$session=new session(your db connect adapter);

数据库链接Ioopen提供大家一个PDO的方法,参照使用:

function connect_db($arrPDODB){$db=new PDO($arrPDODB['db_driver'].’:host=’.$arrPDODB['db_host'].’;dbname=’.$arrPDODB['db_name'],$arrPDODB['db_user'],$arrPDODB['db_password']);$db->query(”set names ‘utf8′”);return $db;}

因此,上面声明对象部分你可以这样写:

$session=new session(connect_db($arrPDODB));

接下来:

//设置色session id的名字ini_set(‘session.name’, ‘sid’);//不使用 GET/POST 变量方式ini_set(‘session.use_trans_sid’, 0);//设置垃圾回收最大生存时间ini_set(‘session.gc_maxlifetime’, 3600);//使用 cookie 保存 session ID 的方式ini_set(‘session.use_cookies’, 1);ini_set(‘session.cookie_path’, ‘/’);//多主机共享保存 session id 的 cookie,注意此处域名为一级域名ini_set(‘session.cookie_domain’, ‘*.xxx.com’);//将 session.save_handler 设置为 user,而不是默认的 filessession_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’));

以上都是SESSION的设置,不明白的多搜索下手册,Ioopen喜欢刨根究底这样的学习方式,这样你可以学透一个知识点,而不是知道一知半解,就认为自己懂了或者会了.

最后,在你需要的地方将SESSION启动:

session_start();

转载于:https://my.oschina.net/ioopen/blog/66090

你可能感兴趣的文章
Asp.net mvc 3.0新特性-浅析1
查看>>
Hadoop FSDataInputStream 流定位的例子
查看>>
在OWA页面中,增加忘记密码项
查看>>
Samba文件共享服务(共享脚本 让你工作更轻松)
查看>>
AJAX 学习笔记[三] get 与post 模式的区别
查看>>
MES技术
查看>>
GO语言练习:网络编程 ICMP 示例
查看>>
ios11--UIButton
查看>>
Jq-公告渐隐弹出
查看>>
Windows Forms中通过自定义组件实现统一的数据验证(二)
查看>>
阿里云海外征战记:跻身全球前三,只用了两年半
查看>>
解密回声消除技术之二(应用篇)
查看>>
Go语言的web程序写法
查看>>
IDF2011:基于SaaS模式的"教学云"案例
查看>>
《Linux From Scratch》第三部分:构建LFS系统 第七章:基本系统配置- 7.5. 配置系统时间...
查看>>
云计算你必须思考的8大问题
查看>>
Windows7 Debug Test
查看>>
HTTPS连接的前几毫秒发生了什么
查看>>
从变量到封装:一文带你为机器学习打下坚实的Python基础
查看>>
给大家共享一个基本算法包
查看>>