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 相关文章推荐
php桌面中心(二) 数据库写入
Mar 11 PHP
ThinkPHP缓存方法S()概述
Jun 13 PHP
PHP遍历数组的三种方法及效率对比分析
Feb 12 PHP
php通过array_unshift函数添加多个变量到数组前端的方法
Mar 18 PHP
php实现随机显示图片方法汇总
May 21 PHP
php编写简单的文章发布程序
Jun 18 PHP
浅析Yii2中GridView常见操作
Apr 22 PHP
php reset() 函数指针指向数组中的第一个元素并输出实例代码
Nov 21 PHP
PHP实现的统计数据功能详解
Dec 06 PHP
thinkphp3.2中实现phpexcel导出带生成图片示例
Feb 14 PHP
laravel 实现上传图片到本地和前台访问示例
Oct 21 PHP
phpQuery解析HTML乱码问题(补充官网未列出的乱码解决方案)
Apr 01 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
PHP开启gzip页面压缩实例代码
2010/03/11 PHP
php数组函数序列之array_flip() 将数组键名与值对调
2011/11/07 PHP
PHP二维关联数组的遍历方式(实例讲解)
2017/10/18 PHP
PHP中实现中文字串截取无乱码的解决方法
2018/05/29 PHP
Yii2框架实现登陆添加验证码功能示例
2018/07/12 PHP
一个js写的日历(代码部分网摘)
2009/09/20 Javascript
javascript 函数及作用域总结介绍
2013/11/12 Javascript
JS 打印界面的CSS居中代码适用所有浏览器
2014/03/19 Javascript
jQuery模拟点击A标记示例参考
2014/04/17 Javascript
jQuery实现鼠标滚轮动态改变样式或效果
2015/01/05 Javascript
jQuery设置单选按钮radio选中/不可用的实例代码
2016/06/24 Javascript
AngularJS中的JSONP实例解析
2016/12/01 Javascript
微信小程序 本地存储及登录页面处理实例详解
2017/01/11 Javascript
Angularjs在360兼容模式下取数据缓存问题的解决办法
2017/06/22 Javascript
详谈表单格式化插件jquery.serializeJSON
2017/06/23 jQuery
vue2.0 keep-alive最佳实践
2017/07/06 Javascript
seaJs使用心得之exports与module.exports的区别实例分析
2017/10/13 Javascript
AngularJS实现自定义指令及指令配置项的方法
2017/11/20 Javascript
react 父子组件之间通讯props
2018/09/08 Javascript
原生JS实现前端本地文件上传
2018/09/08 Javascript
ant design vue 表格table 默认勾选几项的操作
2020/10/31 Javascript
vue前端和Django后端如何查询一定时间段内的数据
2021/02/28 Vue.js
linux平台使用Python制作BT种子并获取BT种子信息的方法
2017/01/20 Python
Python3实现取图片中特定的像素替换指定的颜色示例
2019/01/24 Python
Python爬虫回测股票的实例讲解
2021/01/22 Python
Canvas引入跨域的图片导致toDataURL()报错的问题的解决
2018/09/19 HTML / CSS
New Balance英国官方网站:始于1906年,百年慢跑品牌
2016/12/07 全球购物
巴西购物网站:Estrela10
2018/12/13 全球购物
初中语文教学反思
2014/02/02 职场文书
询价采购方案
2014/06/09 职场文书
乡镇党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
工程承包协议书范本
2014/09/29 职场文书
顶岗实习协议书
2015/01/29 职场文书
如果用一句诗总结你的上半年,你会用哪句呢?
2019/07/16 职场文书
纯CSS实现酷炫的霓虹灯效果
2021/04/13 HTML / CSS
SQL bool盲注和时间盲注详解
2022/07/23 SQL Server