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 相关文章推荐
Windows PHP5和Apache的安装与配置
Jun 08 PHP
PHP中使用php5-ffmpeg撷取视频图片实例
Jan 07 PHP
PHP中实现crontab代码分享
Mar 26 PHP
ThinkPHP在Cli模式下使用模板引擎的方法
Sep 25 PHP
深入浅析用PHP实现MVC
Mar 02 PHP
php处理带有中文URL的方法
Jul 11 PHP
thinkPHP线上自动加载异常与修复方法实例分析
Dec 01 PHP
laravel框架查询数据集转为数组的两种方法
Oct 10 PHP
PHP设计模式入门之状态模式原理与实现方法分析
Apr 26 PHP
php实现的证件照换底色功能示例【人像抠图/换背景图】
May 29 PHP
PHP基于phpqrcode类生成二维码的方法示例详解
Aug 07 PHP
通过代码实例解析PHP session工作原理
Dec 11 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
是否存在第一台收音机的说法
2021/03/01 无线电
php 破解防盗链图片函数
2008/12/09 PHP
获取远程文件大小的php函数
2010/01/11 PHP
PHP全概率运算函数(优化版) Webgame开发必备
2011/07/04 PHP
PHP中的生成XML文件的4种方法分享
2012/10/06 PHP
PHP两种快速排序算法实例
2015/02/15 PHP
PHP调用存储过程返回值不一致问题的解决方法分析
2016/04/26 PHP
laravel通过a标签从视图向控制器实现传值
2019/10/15 PHP
客户端静态页面玩分页
2006/06/26 Javascript
Node.js:Windows7下搭建的Node.js服务(来玩玩服务器端的javascript吧,这可不是前端js插件)
2011/06/27 Javascript
jQuery bxCarousel实现图片滚动切换效果示例代码
2013/05/15 Javascript
JS Date函数整理方便使用
2013/10/23 Javascript
table insertRow、deleteRow定义和用法总结
2014/05/14 Javascript
JS正则表达式验证账号、手机号、电话和邮箱是否合法
2017/03/08 Javascript
nodejs实现大文件(在线视频)的读取
2020/10/16 NodeJs
layer弹出层父子页面事件相互调用方法
2018/08/17 Javascript
详解Vue中watch的详细用法
2018/11/28 Javascript
JavaScript常见事件处理程序实例总结
2019/01/05 Javascript
微信小程序封装的HTTP请求示例【附升级版】
2019/05/11 Javascript
Javascript 模拟mvc实现点餐程序案例详解
2020/12/24 Javascript
Python 出现错误TypeError: ‘NoneType’ object is not iterable解决办法
2017/01/12 Python
python实现扑克牌交互式界面发牌程序
2020/04/22 Python
Pycharm中安装wordcloud等库失败问题及终端通过pip安装的Python库如何添加到Pycharm解释器中(推荐)
2020/05/10 Python
python 实现图像快速替换某种颜色
2020/06/04 Python
举例详解HTML5中使用JSON格式提交表单
2015/06/16 HTML / CSS
CSS3 画基本图形,圆形、椭圆形、三角形等
2016/09/20 HTML / CSS
印尼综合在线预订网站:Tiket.com(机票、酒店、火车、租车和娱乐)
2018/10/11 全球购物
英国森林假期:Forest Holidays
2021/01/01 全球购物
境外导游求职信
2014/02/27 职场文书
党员大会主持词
2014/04/02 职场文书
文明寄语大全
2014/04/11 职场文书
党员个人对照检查材料范文
2014/09/24 职场文书
2014小学二年级班主任工作总结
2014/12/05 职场文书
和谐拯救危机观后感
2015/06/15 职场文书
《攀登者》:“海拔8000米以上,你不能指望任何人”
2019/11/25 职场文书
Go本地测试解耦任务拆解及沟通详解Go本地测试的思路沟通的重要性总结
2022/06/21 Golang