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


Posted in PHP onSeptember 18, 2019

本文实例讲述了php实现多站点共用session实现单点登录的方法。分享给大家供大家参考,具体如下:

最近闲来无事,总结整理下单点登录的问题。

单点登录的基本原理为:客户端共享sesionid,服务器端共享session信息。通过共同的sessionid在服务器端获得相同session信息,即可达到单点登录(即多站点共享用户信息,一处登录,处处可用)的目的。

单点登录分为两种情况:

一、站点部署在同一个服务器,且使用同一个二级域名

这种情况下,比较好解决。

1、首先解决站点在客户端sessionid(存在cookie中)的共享问题。使用ini_set()函数即可指定cookie的域,如下: ini_set('session.cookie_domain', '.xxxx.com');//设置服务器cookie的域,xxxx为公用二级域名

2、其次解决站点在服务端的session信息的共享。因为站点在同一个服务器,所以生成的session文件是可以公用的,可以直接使用sessionid获取对应的session信息。

二、站点部署在不同的服务器,使用不同域名

这种情况比较复杂,因为站点在不同服务器使用不同域名,在客户端不能使用ini_set设置cookie的作用域,在服务器端也是各自生成自己的session文件,不能共用,但还是用解决的办法。

1、首先解决客户端sessionid同步问题。

假设我们有三个站点,域名分别是aa.com,bb.com,cc.com。我们在aa.com上建立一个共用的登陆入口login.php,三个网站的登陆请求全部跳转到该页面。代码流程如下:

$back = login($name,$pwd);//执行登陆操作,成功就写入session
//如果登录成功,进行以下操作流程
if($back){
  $sessionid = session_id();
  $key = encode($session,$keyword);//生成安全码
  //输出一个登陆成功提示页,并跳转到请求登陆的站点
}

在登陆成功html提示页面中添加如下代码,利用iframe标签请求需要同步登陆的站点

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

aa.com和cc.com站点的set_cookie.php文件如下

//解密$key
decode($key);
//把当前站点的sessionid设置为传递的sessionid
session_id($_GET['sessionid']);
session_start();

2、解决三个站点服务器端共享session的问题。

前面已经说过,因为三个站点不在同一个服务器,因此会生成各自的session文件,如果想要共享这些文件,又面临跨域等一系列问题。所以我们转化思路,不使用文件保存session信息,而是把session信息保存到数据库中。这样,只要获得session信息的sessionid,任何站点都可以访问相同的session信息。

我们创建一个mysql_session.php文件,用于存储session信息到数据库,代码如下

$gb_DBname="test";            //数据库名称
$gb_DBuser="root";            //数据库用户名称
$gb_DBpass="";              //数据库密码
$gb_DBHOSTname="127.0.0.1";        //主机的名称或是IP地址
$SESS_DBH="";              //数据库对象
session_module_name("User");      //定义session存储按用户定义的方式
$SESS_LIFE=get_cfg_var("session.gc_maxlifetime");//得到session的最大有效期,也可以自定义
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)){
  echo "MySql Error:".mysql_error()."";
  die();
  }
  if(!mysql_select_db($gb_DBname,$SESS_DBH)){
  echo "MySql Error:".mysql_error()."";
  die();
  }
  return true;
}
function sess_close(){
return true;
}
function sess_read($key)
{
  global $SESS_DBH,$SESS_LIFE;
  $qry="select value from db_session where sesskey = '$key' and expiry > ".time();
  $qid=mysql_query($qry,$SESS_DBH);
  if(list($value)=mysql_fetch_row($qid)){
  return $value;
  }
  return false;
}
//写入session信息。保存session信息的数据表名为:db_session
//除了主键自增id,需要的字段如下
//sesskey  sessionid
//values  session值
//expiry  session的到期日期
function sess_write($key,$val)
{
  global $SESS_DBH,$SESS_LIFE;
  $expiry=time()+$SESS_LIFE;
  $value=$val;
  $qry="insert into db_session values('$key',$expiry,'$value')";
  $qid=mysql_query($qry,$SESS_DBH);
  if(!$qid){
  $qry="update db_session set expiry=$expiry, value='$value' where sesskey='$key' and expiry >".time();
  $qid=mysql_query($qry,$SESS_DBH);
  }
  return $qid;
}
function sess_destroy($key)
{
  global $SESS_DBH;
  $qry="delete from db_session where sesskey = '$key'";
  $qid=mysql_query($qry,$SESS_DBH);
  return $qid;
}
function sess_gc($maxlifetime)
{
  global $SESS_DBH;
  $qry="delete from db_session where expiry < ".time();
  $qid=mysql_query($qry,$SESS_DBH);
  return mysql_affected_rows($SESS_DBH);
}
session_set_save_handler("sess_open","sess_close","sess_read","sess_write","sess_destroy","sess_gc");

之后在需要使用session的页面中,在session_start()之前引入该文件,其他的跟平时使用seesion一样就可以了。你会发现你赋值的session已经被存进了数据库中。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
WINXP下apache+php4+mysql
Nov 25 PHP
中篇:安装及配置PHP
Dec 13 PHP
PHP学习 变量使用总结
Mar 24 PHP
ThinkPHP自动验证失败的解决方法
Jun 09 PHP
使用Discuz关键词服务器实现PHP中文分词
Mar 11 PHP
实用的PHP带公钥加密类分享(每次加密结果都不一样哦)
Aug 20 PHP
PHP函数nl2br()与自定义函数nl2p()换行用法分析
Apr 02 PHP
php file_get_contents取文件中数组元素的方法
Apr 01 PHP
ThinkPHP 3使用OSS的方法
Jul 19 PHP
YII2框架中actions的作用与使用方法示例
Mar 13 PHP
通过PHP实现用户注册后邮箱验证激活
Nov 10 PHP
PHP ob缓存以及ob函数原理实例解析
Nov 13 PHP
PHP实现批量修改文件名的方法示例
Sep 18 #PHP
php DES加密算法实例分析
Sep 18 #PHP
php实现QQ小程序发送模板消息功能
Sep 18 #PHP
php文件后缀不强制为.php的实操方法
Sep 18 #PHP
php校验公钥是否可用的实例方法
Sep 17 #PHP
php写入mysql中文乱码的实例解决方法
Sep 17 #PHP
php写入txt乱码的解决方法
Sep 17 #PHP
You might like
现磨咖啡骗局!现磨咖啡=新鲜咖啡?现磨咖啡背后的猫腻你不懂!
2019/03/28 冲泡冲煮
php根据isbn书号查询amazon网站上的图书信息的示例
2014/02/13 PHP
通过PHP自带的服务器来查看正则匹配结果的方法
2015/12/24 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
yii2.0整合阿里云oss的示例代码
2017/09/19 PHP
PHP如何实现订单的延时处理详解
2017/12/30 PHP
script的async属性以非阻塞的模式加载脚本
2013/01/15 Javascript
JQuery分别取得每行最后一列和最后一行的示例代码
2013/08/18 Javascript
Jquery实现侧边栏跟随滚动条固定(兼容IE6)
2014/04/02 Javascript
AngularJS实现表单验证
2015/01/28 Javascript
avalon js实现仿微博拖动图片排序
2015/08/14 Javascript
Bootstrap编写导航栏和登陆框
2016/05/30 Javascript
jQuery Easyui快速入门教程
2016/08/21 Javascript
浅析vue数据绑定
2017/01/17 Javascript
对于input 框限定输入值为浮点型的js代码
2017/09/25 Javascript
如何抽象一个Vue公共组件
2017/10/17 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
2018/09/21 Javascript
JavaScript学习笔记之数组基本操作示例
2019/01/09 Javascript
Vue使用预渲染代替SSR的方法
2020/07/02 Javascript
vue项目实现设置根据路由高亮对应的菜单项操作
2020/08/06 Javascript
vue+Element-ui前端实现分页效果
2020/11/15 Javascript
python使用paramiko实现远程拷贝文件的方法
2016/04/18 Python
使用python实现简单五子棋游戏
2019/06/18 Python
bluepy 一款python封装的BLE利器简单介绍
2019/06/25 Python
在python image 中安装中文字体的实现方法
2019/08/22 Python
python3 selenium自动化 frame表单嵌套的切换方法
2019/08/23 Python
利用Pytorch实现简单的线性回归算法
2020/01/15 Python
通过python检测字符串的字母
2020/02/18 Python
Python中logging日志库实例详解
2020/02/19 Python
Python3爬虫带上cookie的实例代码
2020/07/28 Python
python利用opencv实现颜色检测
2021/02/23 Python
值得收藏的HTML5资源(学习html5的朋友可以收藏下)
2010/07/20 HTML / CSS
实例讲解HTML5的meta标签的一些应用
2015/12/08 HTML / CSS
AmazeUI 图标的示例代码
2020/08/13 HTML / CSS
信息与计算机科学职业规划范文:成为一艘有方向的船
2014/09/11 职场文书
2016年清明节红领巾广播稿
2015/12/17 职场文书