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 相关文章推荐
PHP 数据库树的遍历方法
Feb 06 PHP
PHP 强制下载文件代码
Oct 24 PHP
解析thinkphp的左右值无限分类
Jun 20 PHP
php中引用符号(&amp;)的使用详解
Nov 13 PHP
PHP生成图片验证码、点击切换实例
Jun 25 PHP
学习php中的正则表达式
Aug 17 PHP
ThinkPHP中关联查询实例
Dec 02 PHP
php中return的用法实例分析
Feb 28 PHP
浅谈Yii乐观锁的使用及原理
Jul 25 PHP
php封装db类连接sqlite3数据库的方法实例
Dec 19 PHP
php设计模式之工厂模式用法经典实例分析
Sep 20 PHP
浅谈PHP array_search 和 in_array 函数效率问题
Oct 15 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获取数组中指定的一列实例
2017/12/27 PHP
jquery与google map api结合使用 控件,监听器
2010/03/04 Javascript
jQuery 美元符冲突的解决方法
2010/03/28 Javascript
使用jQuery模板来展现json数据的代码
2010/10/22 Javascript
jquery获取URL中参数解决中文乱码问题的两种方法
2013/12/18 Javascript
jQuery检测返回值的数据类型
2015/07/13 Javascript
Javascript 计算字符串在localStorage中所占字节数
2015/10/21 Javascript
基于javascript制作微博发布栏效果
2016/04/04 Javascript
学习使用bootstrap的modal和carousel
2016/12/09 Javascript
Angular.JS去掉访问路径URL中的#号详解
2017/03/30 Javascript
Ionic2调用本地SQlite实例
2017/04/22 Javascript
自定义事件解决重复请求BUG的问题
2017/07/11 Javascript
VUE单页面切换动画代码(全网最好的切换效果)
2019/10/31 Javascript
深入了解JS之作用域和闭包
2020/06/16 Javascript
Linux下Python获取IP地址的代码
2014/11/30 Python
python基础教程之分支、循环简单用法
2016/06/16 Python
python中json格式数据输出的简单实现方法
2016/10/31 Python
python实现推箱子游戏
2020/03/25 Python
利用Python复制文件的9种方法总结
2019/09/02 Python
tensorflow查看ckpt各节点名称实例
2020/01/21 Python
Python查找不限层级Json数据中某个key或者value的路径方式
2020/02/27 Python
django xadmin中form_layout添加字段显示方式
2020/03/30 Python
Python字符串格式化常用手段及注意事项
2020/06/17 Python
html5贪吃蛇游戏使用63行代码完美实现
2013/06/25 HTML / CSS
斯洛伐克最大的婴儿食品和用品网上商店:Feedo.sk
2020/12/21 全球购物
J2EE模式面试题
2016/10/11 面试题
个人思想理论学习的自我鉴定
2013/11/30 职场文书
学习教师法的心得体会
2014/09/03 职场文书
科长个人四风问题整改措施思想汇报
2014/10/13 职场文书
2015年清明节网上祭英烈活动总结
2015/03/26 职场文书
2015中学学校工作总结
2015/07/20 职场文书
车间安全生产管理制度
2015/08/06 职场文书
2016年大学生就业指导课心得体会
2015/10/09 职场文书
大学迎新生的欢迎词
2019/06/25 职场文书
SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用
2021/06/30 SQL Server
排查并解决MySQL生产库内存使用率高的报警
2022/04/11 MySQL