PHP实现跨服务器session共享的方法教程
今天带来PHP实现跨服务器session共享的方法教程。
本文实例讲述了PHP实现cookie跨域session共享的方法。分享给大家供大家参考,具体如下:
做过web开发的小伙伴们都了解cookie和session,cookie是存储在客户端的,session是存储在服务器的。
本篇主要通过一些实践中的案例和大家分享一下踩到坑,重点说明了cookie跨域问题和session服务器共享问题,以php语言为使用语言进行说明。
先聊聊cookie
设置cookie无效
| 
 1 
 | 
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值获取不到
先看这样一段代码
| 
 1 
2 
 | 
setcookie("sso", "e589hR6VnO8K1CNQZ4PSP/LWGBhRKE5VckawQwl1TdE8d4Q5E7tW", time() + 900);var_dump($_COOKIE["sso"]); | 
要解决这个问题,要先了解一下setcookie后发生了什么?因为cookie是保存在客户端的,php是服务端语言,实际上setcookie之后只是在返回的http头增加一个cookie的头信息,告诉客户端需要设置一个酱紫的cookie,如下图:

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代码:
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
 | 
<?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页面
| 
 1 
2 
3 
4 
 | 
<?phpsetcookie("sso", $_GET["sso"]);?><iframe src="http://a.com/callback.php"></iframe> | 
a.com的callback.php页面
| 
 1 
2 
3 
 | 
<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目录下。
| 
 1 
2 
3 
4 
 | 
session_start();echo session_id();//本例输出ipkl446enhae25uq92c28u4lo3$_SESSION['name'] = "tony”;$_SESSION['users'] = array("tony", "andy"); | 
通过session_id方法可以取到当前的session编号,通过这个编号可查看一下该session文件。
| 
 1 
2 
 | 
$ sudo more /var/tmp/sess_ipkl446enhae25uq92c28u4lo3name|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中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进行调整
| 
 1 
2 
 | 
ini_set("session.save_handler", "redis");ini_set("session.save_path", "tcp://127.0.0.1:6379”); | 
如果需要使用redis进行存储,需要session中的Registered save handlers支持redis

php中session是否支持redis
当这样设置之后,session就会保存在redis中了,不同的集群服务器之间就可以通过该redis服务器进行共享了。
好吧,暂时就写到这里了,以后会发现新的坑会继续补充上来。
PHP实现跨服务器session共享的方法教程的更多相关文章
- 跨应用Session共享
		
摘要:虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术.本文将详细讨论session的工作机制并且对在Java ...
 - 用redis实现跨服务器session(转)
		
这个月我们新开发了一个项目,由于使用到了4台机器做web,使用dns做负载均衡, 上面图上用户通过DNS的调度(一个域名对应多个ip)分别访问到VM2-VM5上,四台机器都访问VM1上的redis,两 ...
 - [转载]用redis实现跨服务器session
		
地址:http://blog.chinaunix.net/uid-11121450-id-3284875.html 这个月我们新开发了一个项目,由于使用到了4台机器做web,使用dns做负载均衡, 上 ...
 - PHP多台服务器跨域SESSION共享
		
网站业务规模和访问量的逐步发展,原本由单台服务器.单个域名的迷你网站架构已经无法满足发展需要. 此时我们可能会购买更多服务器,并且启用多个二级子域名以频道化的方式,根据业务功能将网站分布部署在独立的服 ...
 - Windows 环境下分布式跨域Session共享(转)
		
出处:http://www.cnblogs.com/stangray/p/3328092.html 为什么还是那句话,在网上找了N篇Session共享,但真正可以直接解决问题的还是没有找到. 一.以下 ...
 - Windows 环境下分布式跨域Session共享
		
为什么还是那句话,在网上找了N篇Session共享,但真正可以直接解决问题的还是没有找到. 一.以下为本人亲测,为防止环境不一致,对本文产生歧义,限定环境如下: 1. IIS7.0 2. Asp.ne ...
 - 负载均衡服务器session共享的解决方案
		
在ASP.NET的程序中要使用Session对象时,必须确保页面的@page指令中EnableSessionState属性是True或者Readonly,并且在web.config文件中正确的设置了S ...
 - session以及分布式服务器session共享
		
一.session的本质 http协议是无状态的,即你连续访问某个网页100次和访问1次对服务器来说是没有区别对待的,因为它记不住你. 那么,在一些场合,确实需要服务器记住当前用户怎么办?比如用户登录 ...
 - PHP + Memcache 实现多服务器session共享
		
很多时候一个完整的系统可能运行在多个服务器上,如果这多个服务器之间需要共享session的话,那么php默认的files保存session的方式就无能为力了.这时我们可以考虑使用memcache 来接 ...
 
随机推荐
- QTP 11 补丁大全
			
原文: http://relevantcodes.com/qtp-11-0-patches/ Patch Link Details Support for Chrome 19 QTPWEB_00102 ...
 - postman+newman+jenkins接口自动化
			
postman用来做接口测试非常方便,接口较多时,则可以实现接口自动化 目录 1.环境准备 2.本机调试脚本 3.集成jenkins 1.环境准备 1.1安装nodejs6.0+ 安装nodejs6. ...
 - 类BigDecimal
			
/* * float和double类型的数据存储和int不一样 * * float和double类型容易丢失精度 * * 因此使用BigDecimal * * BigDecimal类描述:不可变的,任 ...
 - c# WPF——创建带有图标的TreeView
			
1.使用数据模板对TreeViewItem进行更改 2.xaml中重写TreeviewItem的控件模板 3.继承TreeViewItem(TreeView中的元素),后台进行控件重写.(介绍此方法) ...
 - MVC 源码系列之路由(二)
			
MVCParseData和Match方法的实现 ### ParseData 那么首先要了解一下ParseData. //namespace Route public string Url { get ...
 - Altium Designer chapter8总结
			
元件库操作中需要注意如下: (1)原理图库:主要分三部分来完成(绘制元件的符号轮廓.放置元件引脚.设计规则检查). (2)多子件原理图库:操作与原理图库基本相同,就是新建part. (3)PCB封装库 ...
 - 前端005/React生命周期
			
ES6中React生命周期 一.React生命周期 React生命周期主要包括三个阶段:初始化阶段.运行中阶段和销毁阶段. 在React不同的生命周期里,会依次触发不同的钩子函数. 二.React的生 ...
 - [Git] 001 初识 Git 与 GitHub 之新建仓库
			
在 GitHub 的 UI 界面使用 Git 新建一个仓库 1. 点击右上角的 +,选择 New repository 2. 网站会自动跳转至新页面,在下框中填入仓库名 仓库名也有讲究,挖个坑,日后填 ...
 - [Web 前端] 011 css 背景属性
			
1. 概览 参数 释义 background-color 背景颜色 background-image 背景图片 background-repeat 是否重复 background-position 定 ...
 - 移动端的设备提供了一个事件:orientationChange事件
			
移动端的设备提供了一个事件:orientationChange事件:https://blog.csdn.net/gong1422425666/article/details/79001836