`

PHP多台服务器跨域SESSION共享

php 
阅读更多

稍微大一点的网站,通常都会有不只一个服务器,每个服务器运行着不同的功能模块或者不同的子系统,他们使用不同的二级域名,比如www.a.com、i.a.com、bbs.a.com。而一个整体性强的网站,用户系统是统一的,即一套用户名、密码在整个网站的各个子系统中都是可以登录使用的。各个服务器共享用户数据是比较容易实现的,只需要在后端放个数据库服务器,各个服务器通过统一接口对用户数据进行访问即可。但还存在一个问题,就是用户在i.a.com登录之后,进入www.a.com时,仍然需要重新登录,基本的通行证的问题,映射到技术上,其实就是各个服务器之间如何实现共享 SESSION 数据的问题。

为了解决这个问题,我们采用将 SESSION 的数据保存数据库的方式。关于PHP SESSION的扫盲这里就不在累赘。在默认情况下,各个服务器会各自分别对同一个客户端产生 SESSION ID,如对于同一个用户浏览器,www.a.com系统产生的 SESSION ID 是a0211e9de3192ba6c22992d27a1b6a0a,而i.a.com生成的则是277003f262f0c366946a86a28ba431d8。另外,PHP 的 SESSION 数据都是分别保存在本服务器的文件系统中。

想要共享 SESSION 数据,那就必须实现两个目标:www.a.com和i.a.com所产生的SESSION ID相同,并且可通过同一个 COOKIE 进行传递,也就是说各个服务器必须可以读取同一个名为 PHPSESSID 的 COOKIE;另一个是 SESSION 数据必须存放在一个各个系统都能访问到的地方。简单地说就是多服务器共享客户端的 SESSION ID,同时还必须共享服务器端的 SESSION 数据。

第一个目标的实现其实很简单,只需要对 COOKIE 的域(domain)进行特殊地设置即可,默认情况下,COOKIE 的域是当前服务器的域名/IP 地址,而域不同的话,各个服务器所设置的 COOKIE 是不能相互访问的,如 www.a.com 的服务器是不能读写 www.b.com 服务器设置的 COOKIE 的。这里我们所说的同一网站的服务器有其特殊性,那就是他们同属于同一个一级域,如:www.a.com 和 i.a.com 都属于域 .a.com,那么我们就可以设置 COOKIE 的域为 .a.com,这样 www.a.com、i.aaa.com 等等都可以访问此 COOKIE。PHP 代码中的设置方法如下:

ini_set('session.cookie_domain', '.a.com');

 这样各个系统共享同一客户端 SESSION ID 的目的就达到了,下面就是共享SESSION数据,我们就将SESSION数据放在数据库中,首先建立数据库表:

CREATE TABLE sessions (
 session_id varchar(32) NOT NULL,
 session_last_access int(10) unsigned,
 session_data text,
 PRIMARY KEY (session_id)

 session_id为主键,保存SESSION ID ,session_last_access是SESSION最后更新时间,session_data是SESSION数据。

PHP 提供了session_set_save_handle() 函数,可以用此函数自定义 SESSION 的处理过程,当然首先要先将 session.save_handler 改成 user,可在 PHP 中进行设置:
接下来着重讲一下 session_set_save_handle() 函数,此函数有六个参数:
session_set_save_handler ( string open, string close, string read, string write, string destroy, string gc )
各个参数为各项操作的函数名,这些操作依次是:打开、关闭、读取、写入、销毁、垃圾回收。PHP 手册中有详细的例子,详细代码如下:

$gb_DBHOSTname = "127.0.0.1"; //主机的名称或是IP地址
$gb_DBname = "dbname"; //数据库名称
$gb_DBuser = "username"; //数据库用户名称
$gb_DBpass = "pwd"; //数据库密码
$gb_COOKIE_DOMAIN = '.a.com';
$SESS_DBH = "";
$SESS_LIFE = get_cfg_var("session.gc_maxlifetime"); //得到session的最大有效期。
 session_id(); //不使用 GET/POST 变量方式
ini_set('session.use_trans_sid', 0); //设置垃圾回收最大生存时间
ini_set('session.gc_maxlifetime', 13600); //使用 COOKIE 保存 SESSION ID 的方式
ini_set('session.use_cookies', 1);
ini_set('session.cookie_path', '/'); //多主机共享保存 SESSION ID 的 COOKIE
ini_set("session.cookie_domain", $gb_COOKIE_DOMAIN);
//将 session.save_handler 设置为 user,而不是默认的 files session_module_name('user');
function sess_open($save_path, $session_name) {
	global $gb_DBHOSTname, $gb_DBname, $gb_DBuser, $gb_DBpass, $SESS_DBH;
	if (!$SESS_DBH = mysql_pconnect($gb_DBHOSTname, $gb_DBuser, $gb_DBpass)) {
		die('MySQL Error');
	}
	mysql_query("SET character_set_connection=utf8, character_set_results=utf8, character_set_client=binary", $SESS_DBH);
	if (!mysql_select_db($gb_DBname, $SESS_DBH)) {
		die('MySQL Error');
	}
	return true;
}

function sess_close() {
	global $SESS_DBH;
	//$SESS_DBH->Close();
	return true;
}

function sess_read($key) {
	global $SESS_DBH, $SESS_LIFE;
//      var_dump($SESS_DBH);
	$qry = "select session_data from sessions where session_id = '$key' ";
	$qid = mysql_query($qry, $SESS_DBH);
//      var_dump($qid);
	if (list ($value) = mysql_fetch_row($qid)) {
		return $value;
	}
	return false;
}

function sess_write($key, $val) {
	global $SESS_DBH, $SESS_LIFE;
	$session_last_access = time();
	$value = $val;
	$qry = "insert into  sessions values('$key',$session_last_access,'$value')";
	$qid = mysql_query($qry, $SESS_DBH);
	if (!$qid) {
		$qry = "update sessions set session_last_access=$session_last_access, session_data='$value' where session_id='$key' ";
		$qid = mysql_query($qry, $SESS_DBH);
	}
	return $qid;
}

function sess_destroy($key) {
	global $SESS_DBH;
	$qry = "delete from sessions where session_id = '$key'";
	$qid = mysql_query($qry, $SESS_DBH);
	return $qid;
}

function sess_gc($maxlifetime) {
	global $SESS_DBH;
	$old = time() - $maxlifetime;
	$old = mysql_real_escape_string($old);
	$qry = "delete from sessions where session_last_access < " . $old;
	$qid = mysql_query($qry, $SESS_DBH);
	return mysql_affected_rows($SESS_DBH);
}
session_module_name();
session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
session_start();

 

 

分享到:
评论

相关推荐

    iframe 跨域访问session

    6. **服务器端代理**:最安全且可靠的方法是不在客户端处理跨域`session`,而是通过服务器端的代理。例如,服务器可以接收来自`iframe`的请求,然后转发到实际的目标,并在响应中包含`session`信息。 在提供的文件...

    跨域共享session (实现http跳转https 共享session)

    综上所述,跨域共享session涉及到多个技术层面,包括浏览器限制、服务器配置、前端处理和安全措施。实现HTTP到HTTPS的session共享需要综合考虑这些因素,并确保在提供便利的同时,保证用户数据的安全。

    session跨域的共享--更改配置

    - **性能考量**:跨域session可能会增加网络负载,因为session数据需要在多个服务器之间同步。因此,优化session数据大小和减少不必要的同步操作是必要的。 - **兼容性**:不同浏览器对于cookie的处理方式可能有所...

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

    Session共享通常用于同一服务器下的多个应用间,或分布式服务器环境。PHP本身并不支持跨服务器的Session共享,但可以通过以下几种方式实现: 1. **数据库存储**:将Session数据存储在数据库中,多个服务器可以共享...

    处理session跨域几种方案

    处理Session跨域问题通常涉及到多个网站或应用之间共享用户身份验证信息。Session是Web应用程序用来存储用户特定数据的一种机制,通常存储在服务器端,而Session ID通过Cookie在客户端与服务器之间传递。当用户在...

    ThinkPHP框架实现session跨域问题的解决方法

    ThinkPHP框架实现session跨域问题的解决方法主要涉及到了两个方面:其一,是PHP自身处理session...同时,还应该了解session.cookie_domain的具体设置方法及其对session共享范围的影响,以实现安全和高效的session管理。

    php中http与https跨域共享session的解决方法

    通过在客户端存储Session ID,并在请求中携带,可以实现在不同协议间的Session共享。然而,必须采取适当的加密和安全措施,以防止Session ID被恶意利用。上述代码示例提供了一个基本的实现方案,但在实际应用中,应...

    PHP简单实现HTTP和HTTPS跨域共享session解决办法

    本篇文章将探讨如何使用PHP实现HTTP和HTTPS之间的session共享,以解决cookie失效问题。 首先,理解session和cookie的关系至关重要。在PHP中,session默认依赖于cookie来存储session ID,这个ID是一个唯一的标识符,...

    6.4: Session与Cookie 、 部署memcached 、 Session共享 、 .docx

    - 要注意的是,当使用Session时,Nginx需要配置负载均衡策略以考虑Session共享,比如使用ip_hash策略,确保同一用户的请求始终被转发到同一台服务器。 6. **部署LNMP环境**: - LNMP代表Linux、Nginx、MariaDB...

    PHP基于memcahe的session方法重写

    为了解决这个问题,我们可以利用memcache(或其升级版memcached)来实现session的存储和共享,从而达到session跨服务器跨域的目的。本文将详细介绍如何基于memcache实现PHP的session方法重写。 首先,memcache是一...

    跨域单点登录

    这样做的好处是可以在多个服务器之间共享session信息,适用于分布式环境。实现时,可以创建一个专门的session存储类,覆盖PHP的默认session处理函数,将session数据保存到文件,并在需要时读取。 CodeIgniter(CI)...

    PHP Session的配置与应用

    此外,Cookie可以跨域共享,Session则不行。 五、实践中的注意事项 1. 安全性:避免在Session中存储敏感信息,如密码明文。使用加密技术保护数据。 2. 性能:大量用户并发时,Session可能导致服务器负载增加,...

    PHP中session全面教程.txt

    2. **Session复制**:在多服务器环境下,可能需要实现Session复制或共享机制,以确保用户在不同的服务器之间切换时不会丢失会话数据。 #### 结语 Session机制是Web开发中非常重要的一个组成部分,它帮助开发者实现...

    Yii2下session跨域名共存的解决方案

    对于不同一级域名之间的session共享,比如`a.com`和`b.com`,一种可行的方法是利用P3P(Platform for Privacy Preferences Project)协议。P3P允许跨域设置cookie,通过在响应头中添加特定的P3P政策,浏览器会允许...

    php实现多站点共用session实现单点登录的方法详解

    它基于客户端的Session ID共享和服务器端的Session信息共享。当用户在其中一个站点登录后,其Session ID被所有关联站点识别并用来获取该用户的Session信息,从而实现全局登录状态。 ### 同一服务器下的多站点单点...

    thinkPHP多域名情况下使用memcache方式共享session数据的实现方法

    通常,PHP默认将session数据存储在服务器本地的文件系统中,这就导致了在一个多服务器环境中,每个服务器都有自己的session存储,不能跨域共享。当用户在一台服务器上登录后,访问另一台服务器时,由于session数据未...

    php客户端与服务器实现交互

    7. **CORS**:跨源资源共享(CORS)允许来自不同源的JavaScript发送请求,PHP需要设置适当的HTTP头来允许跨域请求。 在实践中,我们需要考虑安全性、性能和用户体验。比如,对用户输入进行验证和过滤以防止SQL注入...

    session 检测登陆

    但有时需要实现多个子域名间的共享,可以调整Session配置。同时,为了提高安全性,应使用HTTPS协议传输Session ID,防止中间人攻击,避免Session Hijacking。 6. **优化与性能**:大量用户同时在线时,Session可能...

    session运用,一些简单但是很容易出错的技巧,希望能给大家一些用途

    8. **跨域Session共享**:如果Web应用包含多个子域名,可能需要实现Session共享。这通常需要在服务器端进行特殊配置,例如在PHP中使用`session.cookie_domain`。 9. **会话状态检查**:在处理用户请求时,应先检查...

    h函数session.zip_session

    4. **跨域处理**:如果需要在多个子域名间共享session,可以设置`session.cookie_domain`。 ### 五、session与cookie的比较 `session`和`cookie`都可以用来跟踪用户状态,但它们有以下区别: - 存储位置:`...

Global site tag (gtag.js) - Google Analytics