怎么把session统一到一个域

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么把session统一到一个域相关的知识,希望对你有一定的参考价值。

参考技术A 实现多域名下共用一个SESSION

要实现多域名共享session,首先就得了解SESSION的运行机制。基本概念我就不说了。
session是这样运行的:
用户A访问站点Y,如果站点Y执行了session_start();(以下假定session_start()总是存在)那么会产生一个 session_id,这个session id一般会以COOKIE的形式保存到用户A(我们可以通过在php.ini里设置session.use_only_cookies为1,强制SESSION ID必须以COOKIE传递。)。这时候SESSION ID表现为$_COOKIE['PHPSESSID'];(PHPSESSID可用session_name()函数来修改)
用户A接着访问,这个session id($_COOKIE['PHPSESSID'])就会在A每次访问Y的时候传送到站点Y。
在站点Y上,会有这么一个目录,是用来保存SESSION的实际数据的。站点Y接收到session id,然后通过session id,来获得与SESSION数据的关联,并返回SESSION数据。
可能聪明的你已经想到了,既然服务器端和客户端之间的SESSION是通过一个SESSION ID来联系,并且SESSION数据是以普通文件的形式保存在一个特定的文件夹里。
那么我们要实现不同域名,只需要满足以下两个条件:
1)不同域名的SESSION数据目录统一到一起,或者同步更新。2)对同一个客户,使用统一的一个SESSION ID
第一个条件的实现。
如果是同一台服务器,就不需要进行任何设置了。
如果是集群/分布式的,那么我想也不需要我来说了。。能做分布式应用的,在目录共享方面的经验应该比我丰富。我也没有进行过多服务器的测试,主客观条件的原因都有。
我在这里主要是想说一下第二个条件——使不同的域名,拥有统一的SESSION ID。
那我们应该怎么统一呢?
首先必须在不同域名之间传递这个SESSION ID,且由于 cookie必须是针对域名的,所以传递动作是由客户端来完成。如果传递过程不是由客户端来完成,那么接受传递的域名就不知道针对的是哪个客户。
其次就是修改接受传递的域名下的SESSION ID。
如何传递:
html里,我们可以使用很多种方法。例如
iframe
<iframe src=”"></iframe>
或者.js
<script type=”text/javascript” src=”"></script>
或者是一个img html元素
<img src=”" />
只要能调用某个地址,就行。
在wml里,由于wml script的特点,我们无法使用script这样的形式来调用,而wml里也没iframe..但是我们还是可以通过img来实现传递的。
如何修改:
既然SESSION ID一般情况下是通过COOKIE来传递,那么我们只需要通过传递$_COOKIE['PHPSESSID'];即可。但是如果PHPSESSID被session_name改变了,我们又得修改setcookie中的PHPSESSID..这样就会变得很麻烦。。所以我们可以选择一个session特有的函数session_id来修改$_COOKIE['PHPSESSID'];
需要注意的几点:
如果session.use_only_cookies为0(PHP默认),那么session id有可能会以url或其他形式传递session_id()和session_name必须在session_start()前使用
以下是我写的一个简单的实现多域名的类。如果上面的看不太明白,可以看看我的这个多域名类。这个类是在HTML下以iframe形式实现的。
?
<?phpclass mdSessionfunction mdSession()function set($urls)if (!is_array($urls))$urls=array($urls);foreach ($urls as $value)echo '<span style="position:absolute;visibility:hidden"><iframe src="'.$value.'?'.session_id().'"></iframe></span>';return true;function get()session_id($_SERVER['QUERY_STRING']);session_start();return true;function _set($urls)$obj=new mdSession();return $obj->set($urls);function _get()$obj=new mdSession();return $obj->get();?>?index.php :<?php ? include "mdSession.php";?session_start();$_SESSION['php']="yogurt8";mdSession::_set('http://www.b.com/ses_get.php');var_dump($_SESSION);?>?ses_get.php<?php?include "mdSession.php";mdSession::_get();?>?b.php :?session_start();var_dump($_SESSION);?先访问 http://www.a.com/a.php 然后在 http://www.b.com/b.php 看效果?在firefox 与谷歌浏览器是没问题,但在 Ie 下还是不行

[转]session 跨域共享方案

在讨论session跨域共享问题之前,我们首先要了解session做了什么,没做到什么

HTTP是无状态的,也就是说服务器不知道谁访问过他,但是有时候,又需要我们去保留这个状态比如说用户的登录信息,如果每次访问都要登陆,这个用户体验实在是太糟糕了,session就解决了这个问题,他把用户登陆信息维护在服务端,会生成一个JSessionID给客户端,客户端下次访问的时候就带着这个JSessionID,服务端根据这个ID去查找用户信息。
当然,session的缺点也很明显,session是存在服务器的内存中的,如果session过多会影响服务器的性能。因为session只在一台服务器里,当有多台服务器的时候,访问别的服务器肯定会失败。
明确了session所做的事以及它的缺陷之后,解决session存在的问题就容易多了,下面我简要说一下5种解决方案

Session Sticky
Session复制
Session集中存储
Cookie
Token
Session Sticky :是指让同一客户端的请求,落在同一台服务器上,因为不会落在别的服务器上,所以自然就不会出现跨域问题。但是这个方案的缺点非常的明显,就是不管比采用什么算法,用户的请求落在哪一台服务器上都是由用户来决定的,可能会造成单点压力,并且如果一台服务器出问题,可能会造成一片区域的人无法访问

Session复制 :是指服务器之间互相同步session信息,也就是说每台服务器上都保存着所有的session信息。这样做的缺点也是非常明显的。上文提到过,session是存在内存中的,会严重影响服务器性能,当然,你也可以把他存在数据库中,但是这会大大影响响应速度。还有一个缺点就是,当访问量过大时,由于互相同步的问题,会造成大量的网络开销

Session集中存储:是指把Session集中存储在一个第三方的服务器中,可以是Redis,可以是数据库或是其它什么东西。当需要访问的时候,都去这个服务器去查。这样做也有不小的缺点,首先是单点问题,如果这个服务器宕机,那么所有的服务都是不可用的,所以这里必须做集群,会浪费服务器资源。还有一点是,每次验证都需要来这个服务器来查,会凭白增加一次网络开销,降低访问速度

Cookie :状态信息不再保存在服务端,而是保存在客户端,客户端每次访问服务器的时候,把这个信息带给服务器。但是Cookie也有不少问题,最被人关注的就是安全问题,因为信息是保存在客户端的,就比较容易被人盗取、篡改,当然这些安全问题都是有解决方案的,这不是限制Cookie的主要原因,真正限制Cookie的原因是很多设备不支持Cookie

Token :和Cookie类似,Token也是由客户端来维持状态的,信息存储在客户端内,具有平台无关性。Token实质上是服务端给客户端的一个字符串,上面包含着一些验证信息,相当于一个身份令牌,你拿着这个令牌就能得到他的服务。相比较于Cookie,Token更加的灵活,可以在任何地方生成,基于Token的权限系统是非常容易实现的

当然,解决方案并不只上面5种,我只是列举了几个有代表性的。

方案是用来解决问题的,上面的这些方案没有好不好的说法,只有合不合适的说法,合适的才是最好的。


转自csdn
原文:https://blog.csdn.net/qq_39907763/article/details/79303481









以上是关于怎么把session统一到一个域的主要内容,如果未能解决你的问题,请参考以下文章

微服务统一登陆认证怎么做?JWT ?

单体应用如何做用户登录验证及统一拦截(基于session+cookie的登录逻辑怎么做)

php 怎么把session写入redis

cas+shiro遇到的一个问题:统一注销失败,session的注销跟创建事件都能捕获到,原因是:

19springcloud分布式Session之Spring Session

[转]session 跨域共享方案