zoukankan      html  css  js  c++  java
  • 单点登录解决方案

    一、基本原理

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

    二、解决方案

    (一)站点部署在同一个服务器,同一个域但不同的子域

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

    1、首先解决站点在客户端sessionid(存在cookie中)的共享问题。使用ini_set()函数即可指定cookie的域,如下: 

    ini_set('session.cookie_domain', '.xxxx.com');//设置服务器cookie的域,xxxx为公用二级域名

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

    (二)站点部署在同一个服务器,但域名不同

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

    1、在登陆成功html提示页面中添加如下代码,利用iframe标签或script标签请求需要同步登陆的站点,将session_id传递过去(也可使用其他跨域方式)

    <!--方式一:iframe标签-->
    <iframe width="0" height="0" src="http://aa.com/set_cookie.php?session_id=<?php echo session_id();?>"></iframe>
    <!--方式一:script标签-->
    <script src="http://bb.com/set_cookie.php?session_id=<?php echo session_id();?>"></script>

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

    <?php
    session_id($_GET['session_id']);////把当前站点的sessionid设置为传递的sessionid
    session_start();

     3、aa.com和cc.com站点的set_cookie.php文件中使用了session_start()方法后,无需再重新设置session,此时session已经同步。

    (三)站点部署在不同服务器,且域名不同

    1)首先解决客户端sessionid同步问题,与上述第二种方式相同的解决方案。

    2)解决各站点服务器端共享session的问题

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

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

    <?php
    $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已经被存进了数据库中。

  • 相关阅读:
    TypeScript完全解读(26课时)_2.TypeScript完全解读-基础类型
    Flutter实战视频-移动电商-48.详细页_详情和评论的切换
    Flutter实战视频-移动电商-47.详细页_Flutter_html插件的使用
    TypeScript完全解读(26课时)_1.TypeScript完全解读-开发环境搭建
    [Android] The connection to adb is down, and a severe error has occured
    每日一小练——求质数
    C++语言笔记系列之十八——虚函数(1)
    Android 输入管理服务-输入事件向详细应用的分发
    Android技术归档
    C++编写绚丽的界面
  • 原文地址:https://www.cnblogs.com/jxl1996/p/10160847.html
Copyright © 2011-2022 走看看