PHP实现cookie跨域session共享的方法分析


Posted in PHP onAugust 23, 2019

本文实例讲述了PHP实现cookie跨域session共享的方法。分享给大家供大家参考,具体如下:

做过web开发的小伙伴们都了解cookie和session,cookie是存储在客户端的,session是存储在服务器的。

本篇主要通过一些实践中的案例和大家分享一下踩到坑,重点说明了cookie跨域问题和session服务器共享问题,以php语言为使用语言进行说明。

先聊聊cookie

设置cookie无效

setcookie("sso", "e589hR6VnO8K1CNQZ4PSP/LWGBhRKE5VckawQwl1TdE8d4Q5E7tW", 900);

这个问题很多刚入门php的小伙们都会碰到。这个代码的本意应当是想设置cookie sso的有效期为15分钟,可是执行这个代码后发现没有效果。为什么呢?因为第三个参数expire表示的是过期的时间节点,而不是有效时间,所以如果希望设置cookie为15分钟,正确的做法应当是获取当前的时间戳加上15分钟。

setcookie这个函数还有path、domain参数都比较常用,强烈建议刚学php的小伙们多翻阅手册。php手册地址: http://php.net/manual/zh/index.php

获取cookie值获取不到

先看这样一段代码

setcookie("sso", "e589hR6VnO8K1CNQZ4PSP/LWGBhRKE5VckawQwl1TdE8d4Q5E7tW", time() + 900);
var_dump($_COOKIE["sso"]);

要解决这个问题,要先了解一下setcookie后发生了什么?因为cookie是保存在客户端的,php是服务端语言,实际上setcookie之后只是在返回的http头增加一个cookie的头信息,告诉客户端需要设置一个酱紫的cookie,如下图:

PHP实现cookie跨域session共享的方法分析

php中setcookie返回的http头

而$_COOKIE这个数组里面保存客户端传递上来的cookie。自然第一次刷新的时候因为客户端没有相应的cookie值,所以$_COOKIE是没有sso的信息的。第一次请求过后,因为服务器设置了cookie sso,所以第一次请求过来客户端就有了cookie sso的信息,所以第二次请求的时候就会带上sso的信息,服务端就能通过$_COOKIE取到值了。

cookie跨域问题

这个可以说是cookie中一个比较热门的问题,面试的时候一般很爱聊这方面的问题。

跨域的业务需求大概是酱紫:用户在a.com进行了登录,希望在b.com也同步进行了登录。如果是同一个主域比较简单,可以通过setcookie中的domain参数进行设定:例如有x.a.com和xx.a.com,可以通过设置domain为a.com,从而a.com的所有二级域名都可以共享这一个cookie。基于安全方面的原因,在a.com下面设置domain为b.com是无效的。

那么是否真的没有办法可以实现这个了呢?这个还是有一些奇巧淫技的,这里介绍一种使用内框iframe的方法。

具体思路:在a.com下设置cookie后,嵌入一个iframe框链接b.com的页面,b.com设置好页面cookie后,再嵌入一个a.com的页面,然后通过parent.parent就可以调用最外层的a.com的js方法,从而进行跳转或者一些其它的操作。具体代码示例如下:

假设a.com有页面:login.php和callback.php,b.com有页面synclogin.php

a.com的login.php代码:

<?php
$sso = "e589hR6VnO8K1CNQZ4PSP/LWGBhRKE5VckawQwl1TdE8d4Q5E7tW";
setcookie("sso", $sso);
?>
login success...
<script type="text/javascript">
  function jumpTo() {
    location.href = "http://a.com";
  }
</script>
<iframe src="http://b.com/synclogin.php?sso=<?php echo $sso; ?>"></iframe>

b.com的synclogin.php页面

<?php
setcookie("sso", $_GET["sso"]);
?>
<iframe src="http://a.com/callback.php"></iframe>

a.com的callback.php页面

<script type="text/javascript">
  parent.parent.jumpTo();
</script>

代码看起来也不难,值得一提的是这里嵌入了两个iframe,因为如果只用一个iframe的话,即在b.com的synclogin.php内直接调用父窗体的jumpTo方法,在有些浏览器下会提示没有权限的错误:
Error: Permission denied to access property

这里只是演示了cookie跨域同步的思路,具体细节还有很多可以改进的地方,比如iframe链接的页面可以考虑改成静态的页面,这样效率会比php动态页面快很多,还有像参数校验、多个主域(比如还有c.om)同时登录等等,这里就不再累述。

cookie的总结到这里就结束,如果你感觉有一些收获,可以在页面底部扫码给我打赏哟,感谢O(∩_∩)O~

session

$_SESSION没有值

这个session使用和cookie有一点不太一样,session使用前必须先调用session_start方法。否则会收到一个undefined的错误:
Notice: Undefined variable: _SESSION

session存储在哪

session存储在服务端,但是session究竟是存储在哪呢?php.ini中关于session有一个save_path的选项可以设置存放的目录,如果这个选项没有设置值,那么就存储在系统默认的tmp目录下。默认的tmp目录可以通过sys_get_temp_dir方法取到。

例如在mac下面,php的session一般会存储在/var/tmp目录下。

session_start();
echo session_id();//本例输出ipkl446enhae25uq92c28u4lo3
$_SESSION['name'] = "tony”;
$_SESSION['users'] = array("tony", "andy");

通过session_id方法可以取到当前的session编号,通过这个编号可查看一下该session文件。

$ sudo more /var/tmp/sess_ipkl446enhae25uq92c28u4lo3
name|s:4:"tony";users|a:2:{i:0;s:4:"tony";i:1;s:4:"andy";}

可以清楚的看到session存储数据的结构,其中值是用序列化的方式进行转化存储的。

session也用了cookie

session不是存储在服务端吗,怎么又和cookie扯上关系了?其实想想也简单,因为客户端再请求的时候,服务端怎么样才能知道该客户端的session存储在哪个文件呢?其实也是通过cookie PHPSESSID来进行标识。

PHP实现cookie跨域session共享的方法分析

php中session的cookie标识

php在进行session操作的时候会生成一个session id,而后把这个值以cookie的形式保存在客户端,就是图示中的PHPSESSID了。客户端在下次请求的时候就会带上这个PHPSESSID,服务端就能知道当前客户端对应的session文件了

session超时设置

cookie超时设置比较简单,一个参数就搞定了。session这边有点小麻烦,既不能单独设置cookie PHPSESSID的超时时间,也不能单独设置服务端文件的超时时间。具体的可以参考鸟哥这篇文章:如何设置一个严格30分钟过期的Session,真的非常严谨,赞一下。

session服务器共享

这个问题和cookie的跨域类似,面试的时候也很爱聊这个问题。

以前在做服务器集群的时候会碰到这样的一样问题,就是用户一会访问是处于正常登录状态,一会访问又没有登录了。这个问题偶尔才会出现。跟踪代码下去才发现session没有取到相应的值,想想也是醉了:原来服务器session没有设置共享,session存在在本地文件目录,当用户访问另外一台服务器的时候自然就取不到session了。

解决方法也不难,通过共享的存储在进行服务器之间的共享。这里使用redis的进行session存储。可以通过php.ini配置文件进行调整,也可以在代码中通过ini_set进行调整

ini_set("session.save_handler", "redis");
ini_set("session.save_path", "tcp://127.0.0.1:6379”);

如果需要使用redis进行存储,需要session中的Registered save handlers支持redis

PHP实现cookie跨域session共享的方法分析

php中session是否支持redis

当这样设置之后,session就会保存在redis中了,不同的集群服务器之间就可以通过该redis服务器进行共享了。

好吧,暂时就写到这里了,以后会发现新的坑会继续补充上来。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
mysql中存储过程、函数的一些问题
Feb 14 PHP
PHP通过header实现文本文件下载的代码
Aug 08 PHP
查找mysql字段中固定字符串并替换的几个方法
Sep 23 PHP
PHPMailer使用教程(PHPMailer发送邮件实例分析)
Dec 06 PHP
析构函数与php的垃圾回收机制详解
Oct 28 PHP
php调用shell的方法
Nov 05 PHP
WampServer下安装多个版本的PHP、mysql、apache图文教程
Jan 07 PHP
PHP中的一些常用函数收集
May 26 PHP
php遍历、读取文件夹中图片并分页显示图片的方法
Nov 15 PHP
PHP微信开发之微信录音临时转永久存储
Jan 26 PHP
Ajax+PHP实现的模拟进度条功能示例
Feb 11 PHP
PHP递归算法的简单实例
Feb 28 PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
Aug 23 #PHP
php中错误处理操作实例分析
Aug 23 #PHP
php+js实现的无刷新下载文件功能示例
Aug 23 #PHP
php简单检测404页面的方法示例
Aug 23 #PHP
PHP Redis扩展无法加载的问题解决方法
Aug 22 #PHP
PHP Primary script unknown 解决方法总结
Aug 22 #PHP
php用wangeditor3实现图片上传功能
Aug 22 #PHP
You might like
PHP与jquery实时显示网站在线人数实例详解
2016/12/02 PHP
Jquery为单选框checkbox绑定单击click事件
2012/12/18 Javascript
学习js在线html(富文本,所见即所得)编辑器
2012/12/18 Javascript
javascript date格式化示例
2013/09/25 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
2013/10/24 Javascript
javascript:json数据的页面绑定示例代码
2014/01/26 Javascript
js replace替换所有匹配的字符串
2014/02/13 Javascript
JavaScript淡入淡出渐变简单实例
2015/08/06 Javascript
javascript中日期函数new Date()的浏览器兼容性问题
2015/09/05 Javascript
JavaScript6 let 新语法优势介绍
2016/07/15 Javascript
bootstrap datetimepicker2.3.11时间插件使用
2016/11/19 Javascript
js图片延迟加载(Lazyload)三种实现方式
2017/03/01 Javascript
js实现分页功能
2017/05/24 Javascript
vue在手机中通过本机IP地址访问webApp的方法
2018/08/15 Javascript
vue将单页面改造成多页面应用的方法
2018/11/25 Javascript
详解vue路由篇(动态路由、路由嵌套)
2019/01/27 Javascript
react高阶组件添加和删除props
2019/04/26 Javascript
node.js中 redis 的安装和基本操作示例
2020/02/10 Javascript
[04:44]显微镜下的DOTA2第二期——你所没有注意到的细节
2014/06/20 DOTA
[01:18]PWL开团时刻DAY10——一拳超人
2020/11/11 DOTA
使用Django的模版来配合字符串翻译工作
2015/07/27 Python
Python 通过URL打开图片实例详解
2017/06/01 Python
python MySQLdb使用教程详解
2018/03/20 Python
Python3中正则模块re.compile、re.match及re.search函数用法详解
2018/06/11 Python
python计算二维矩形IOU实例
2020/01/18 Python
python自动脚本的pyautogui入门学习
2020/04/01 Python
css3 实现元素弧线运动的示例代码
2020/04/24 HTML / CSS
EJB timer的种类
2014/10/28 面试题
党员培训思想汇报
2014/01/07 职场文书
企业管理培训感言
2014/01/27 职场文书
企业内部培训方案
2014/02/04 职场文书
军训教官感言
2014/03/02 职场文书
中班幼儿评语大全
2014/04/30 职场文书
本科毕业论文答辩稿
2015/06/23 职场文书
2016元旦主持人开场白
2015/12/03 职场文书
Ajax实现三级联动效果
2021/10/05 Javascript