PHP中session跨子域的三种实现方法


Posted in PHP onJuly 25, 2016

在之前做东西的时候session一般就直接存在数据库中这样就能解决跨域不仅仅是跨子域,但是今天遇到这个问题是,自己要在别人现有的东西上面做修改。由于仅仅是子域当时就想肯定有简单的解决方法,度娘了找到了三种解决办法:

Session主要分两部分:

一个是Session数据,该数据默认情况下是存放在服务器的tmp文件下的,是以文件形式存在。

另一个是标志着Session数据的Session Id,Session ID,就是那个 Session 文件的文件名,Session ID 是随机生成的,因此能保证唯一性和随机性,确保 Session 的安全。一般如果没有设置 Session 的生存周期,则 Session ID 存储在内存中,关闭浏览器后该 ID 自动注销,重新请求该页面后,重新注册一个 session ID。如果客户端没有禁用 Cookie,则 Cookie 在启动 Session 会话的时候扮演的是存储 Session ID Session 生存期的角色。

两个不同的域名网站,想用同一个Session,就是牵扯到Session跨域问题!

默认情况下,各个服务器会各自分别对同一个客户端产生 SESSIONID,如对于同一个用户浏览器,A 服务器产生的 SESSION ID 是 11111111111,而B 服务器生成的则是222222。另外,PHP 的 SESSION数据都是分别保存在本服务器的文件系统中。想要共享 SESSION 数据,那就必须实现两个目标:

一个是各个服务器对同一个客户端产生的SESSION ID 必须相同,并且可通过同一个 COOKIE 进行传递,也就是说各个服务器必须可以读取同一个名为 PHPSESSID 的COOKIE;

另一个是 SESSION 数据的存储方式/位置必须保证各个服务器都能够访问到。这两个目标简单地说就是多服务器(A、B服务器)共享客户端的 SESSION ID,同时还必须共享服务器端的 SESSION 数据。

有三种解决方法:

1.只要在php页面的最开始(要在任何输出之前,并且在session_start()之前)的地方进行以下设置

ini_set('session.cookie_path', '/');
ini_set('session.cookie_domain', '.mydomain.com');
ini_set('session.cookie_lifetime', '1800');

2.在php.ini里设置

session.cookie_path = /
session.cookie_domain = .mydomain.com
session.cookie_lifetime = 1800

3.在php页面最开始的地方(条件同1)调用函数

session_set_cookie_params(1800 , '/', '.mydomain.com');

session 有个Session_id 作为session的惟一标志。

要实现Session子域,实际上是在同一个浏览器中在访问两个A 和B子域时,其session是相同的。

由于session都是保存在服务器端,如何让两台服务器识别这两个请求是由一个浏览器发出的呢?

Cookie是保存在客户端的,服务器通常通过Cookie来识别不同的客户端,因此,可以使用Cookie来保存Session_id, 并将该Cookie设置为父域。

例如,当访问a.sso.com 时,就将session_id 保存在Cookie中。当访问b.sso.com时,则将session_id  从Cookie中取出来,

并通过session_id 去某个持久化容器中获取Session。

例如,当访问a.sso.com 时,就将session_id 保存在Cookie中。当访问b.sso.com时,则将session_id  从Cookie中取出来,

并通过session_id 去某个持久化容器中获取Session。

在本实验中,使用PHP来作为实验语言。

当访问a.sso.com时,则将通过
 

session_start();
 $_SESSION['person'] = "SBSBSBS";
 $session_id = session_id();
 setcookie('name',$session_id,time()+3600*24,'/','SSO.com');

  将session_id 保存在cookie中。

由于在PHP中,session是一个数组,PHP有 serialize() 函数,将数组序列化

$session_value = serialize($_SESSION);

然后将$session_value 保存在数据库中。

在访问b.sso.com时,则从cookie中获取到session_id,然后到数据库中根据session_id将 经过序列化过的session 获取出来

接着就可以对该session进行操作,实现session 跨子域。

由于将session保存在数据库中,存取都是比较费时的操作,因此可以将session保存在缓存中,例如memcached 或者redis中,

这样对session的存取操作就比较快速了。

使用缓存还有个好处就是,通常session有一定得存活时间,如果存在数据库中,还需要保存该session的存活时间,在取出session时,还需要判断其是否失效。

使用缓存存放session就可以在存放的时候设置其存活时间,减少了取出后的失效判断这一个过程。

我的解决方法是在入口出添加如下代码:

ini_set('session.cookie_path', '/');

 ini_set('session.cookie_domain', '.3water.com'); //注意3water.com换成你自己的域名

ini_set('session.cookie_lifetime', '1800');

如图:

站点一

PHP中session跨子域的三种实现方法

站点二

PHP中session跨子域的三种实现方法

 

可以看到两个站点的PHPSESSID是一样的,当然也解决了跨子域名的问题了

以上就是在PHP中session实现跨子域的几种解决方案,希望能帮助到有需要的大家。

PHP 相关文章推荐
PHP 模拟登陆MSN并获得用户信息
May 16 PHP
php HandlerSocket的使用
May 02 PHP
php 解决旧系统 查出所有数据分页的类
Aug 27 PHP
PHP生成不同颜色、不同大小的tag标签函数
Sep 23 PHP
PHP在网页中动态生成PDF文件详细教程
Jul 05 PHP
PHP中filter函数校验数据的方法详解
Jul 31 PHP
php英文单词统计器
Jun 23 PHP
PHP计算近1年的所有月份
Mar 13 PHP
tp框架(thinkPHP)实现三次登陆密码错误之后锁定账号功能示例
May 24 PHP
针对PHP开发安全问题的相关总结
Mar 22 PHP
PHP实现Markdown文章上传到七牛图床的实例内容
Feb 11 PHP
PHP 自动加载类原理与用法实例分析
Apr 14 PHP
Yii2创建控制器(createController)方法详解
Jul 23 #PHP
Yii2主题(Theme)用法详解
Jul 23 #PHP
Yii2创建表单(ActiveForm)方法详解
Jul 23 #PHP
Yii2验证器(Validator)用法分析
Jul 23 #PHP
yii2 RBAC使用DbManager实现后台权限判断的方法
Jul 23 #PHP
Yii2简单实现多语言配置的方法
Jul 23 #PHP
yii2控制器Controller Ajax操作示例
Jul 23 #PHP
You might like
浅析HTTP消息头网页缓存控制以及header常用指令介绍
2013/06/28 PHP
php5.3不能连接mssql数据库的解决方法
2014/12/27 PHP
thinkphp集成前端脚手架Vue-cli的教程图解
2018/08/30 PHP
JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型
2012/10/11 Javascript
使用firebug进行调试javascript的示例
2013/12/16 Javascript
最精简的JavaScript实现鼠标拖动效果的方法
2015/05/11 Javascript
jQuery简单创建节点的方法
2016/09/09 Javascript
Angular2从搭建环境到开发步骤详解
2016/10/17 Javascript
谈谈Vue.js——vue-resource全攻略
2017/01/16 Javascript
IE11下使用canvas.toDataURL报SecurityError错误的解决方法
2017/11/19 Javascript
Vuejs 2.0 子组件访问/调用父组件的方法(示例代码)
2018/02/08 Javascript
JS实现table表格内针对某列内容进行即时搜索筛选功能
2018/05/11 Javascript
angular2路由之routerLinkActive指令【推荐】
2018/05/30 Javascript
推荐几个不错的console调试技巧实现
2019/12/20 Javascript
es6函数之rest参数用法实例分析
2020/04/18 Javascript
vuex页面刷新导致数据丢失的解决方案
2020/12/10 Vue.js
用Python编写一个简单的Lisp解释器的教程
2015/04/03 Python
讲解Python中运算符使用时的优先级
2015/05/14 Python
Android模拟器无法启动,报错:Cannot set up guest memory ‘android_arm’ Invalid argument的解决方法
2016/07/01 Python
浅谈pytorch和Numpy的区别以及相互转换方法
2018/07/26 Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
2019/07/15 Python
Python常用模块os.path之文件及路径操作方法
2019/12/03 Python
DjangoWeb使用Datatable进行后端分页的实现
2020/05/18 Python
CSS3制作ajax loader icon实现思路及代码
2013/08/25 HTML / CSS
使用css3制作动感导航条示例
2014/01/26 HTML / CSS
DJI大疆无人机官方商城:全球领先的无人飞行器研发和生产商
2016/12/21 全球购物
世界上最受欢迎的钓鱼诱饵:Rapala
2019/05/02 全球购物
365 Tickets英国:全球景点门票
2019/07/06 全球购物
如何选择使用结构还是类
2014/05/30 面试题
财务总监岗位职责
2014/03/07 职场文书
幼儿园教研活动总结
2014/04/30 职场文书
2014年应急工作总结
2014/12/11 职场文书
世界气象日活动总结
2015/02/27 职场文书
2015年感恩节活动总结
2015/03/24 职场文书
Java 语言中Object 类和System 类详解
2021/07/07 Java/Android
redis requires ruby version2.2.2的解决方案
2021/07/15 Redis