<转>在PHP中实现单点登录(Single Sign On)的一种简单方法
单点登录是大容量系统必备的功能,市面上有几款昂贵的商业系统,若不是财大气粗,恐怕用不起。
怎么样才能简单、经济的实现这个功能?我们在这里探讨一种可行的方案。
当前开发 Web 应用中,Apache + PHP + MySQL 是中小型企业降低成本的必选架构,这里我们来实现 PHP 的单点登录,让这种经济性的架构能够扩展到的群集服务器层面。
我们的设想是将 PHP 的 Session 数据集中存储,这样对于不同服务器中运行的 PHP 来说,只有一个共有的 Session
数据库,那么用户在服务器 A 登录所生成的 Session 数据在服务器 B、C、D 等服务器都可以共享,就可以免除多次登录。但由于 PHP 的
Session 是需要 Cookie 的,而 Cookie
又是与域名相关的,所以采用这个方案的各个服务器需要有相同的域名(至少是相同的二级域名),比如:
1、所有服务器的域名都是 www.itokit.com,这个东东 DNS 轮询就可以实现;这个时候,在 PHP 中将 Cookie 域名设置为 www.itokit.com 即可;
2、所有服务器的域名都是以 .itokit.com 结尾的二级域名或三级域名,比如
blog.itokit.com,agent.itokit.com 等等,这个时候,在 PHP 中将 Cookie 域名设置为
.itokit.com 就可以共享 Cookie 了。
解决了先决条件,我们现在来看看 PHP 的 Session 存储方法,在 PHP 手册说明中,有一个叫 session_set_save_handler() 的函数,这个函数是用来注册用户自定义的 Session 数据存储接口的。
以下是 PHP 手册自带的示例:
<?php
function open($save_path, $session_name) {
global $sess_save_path, $sess_session_name;
$sess_save_path = $save_path;
$sess_session_name = $session_name;
return(true);
}
function close() {
return(true);
}
function read($id) {
global $sess_save_path, $sess_session_name;
$sess_file = "$sess_save_path/sess_$id";
if ($fp = @fopen($sess_file, "r")) {
$sess_data = fread($fp, filesize($sess_file));
return($sess_data);
} else {
return(""); // Must return "" here.
}
}
function write($id, $sess_data) {
global $sess_save_path, $sess_session_name;
$sess_file = "$sess_save_path/sess_$id";
if ($fp = @fopen($sess_file, "w")) {
return(fwrite($fp, $sess_data));
} else {
return(false);
}
}
function destroy($id) {
global $sess_save_path, $sess_session_name;
$sess_file = "$sess_save_path/sess_$id";
return(@unlink($sess_file));
}
/*********************************************
* WARNING - You will need to implement some *
* sort of garbage collection routine here. *
*********************************************/
function gc($maxlifetime) {
return true;
}
session_set_save_handler("open", "close", "read", "write", "destroy", "gc");
session_start();
// proceed to use sessions normally
?>
按照这种思路,我们只要编写自己的处理函数并进行相应的注册,就可以实现 PHP Session 数据的自定义存储了。
具体实现可以开动你的思路,比如可以使用 NFS 将 Session 数据存储到统一的网络设备中,也可以将 Session 数据保存到一个数据库中,让所有服务器连接这个共享数据库(比如 MySQL)就可以了。
嗯,比较简单,而且经济。
更多考虑:
1、性能需要考量,特别是服务器数(引起资源占用)和用户量(引起 Session 量)非常巨大的时候。
posted on 2015-10-30 16:40 hahahahahai12 阅读(222) 评论(0) 收藏 举报
浙公网安备 33010602011771号