用户操作
[即时聊天] [发私信] [加为好友]
夏纯中ID:danny_xcz
857143次访问,排名41好友2人,关注者84
danny_xcz的文章
原创 296 篇
翻译 3 篇
转载 25 篇
评论 638 篇
纯月的公告
最近评论
zjxzou:bucuo~
yu3350360:收藏了先 呵呵
henhaohll:有些意思啊!呵呵 ..
sap99:www.sap99.com/,SAP99资料多多

SAP免费资料下载
http://www.sap99.com

有很多的学习资料,推荐一下,
snowring:你好,能留下联系方式吗?
我也在研究MULE,QQ:7766284
谢谢了。
文章分类
收藏
    相册
    Blog用途
    我的相册
    Java Desktop
    Open Source
    友情链接
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 纯基于PHP的单点登陆收藏

    新一篇: 传奇美国黑客发表文章说:不要攻击中国大陆网站 | 旧一篇: PHP集成华为企业信息机

     Discuz有一个通行证,类似于单点登陆。不过我觉得单点登陆最好应该是一个独立的程序,和CAS一样。由于所有的程序都是PHP的,所以就做了一个简单的单点登陆。借用了一下discuz的加密方法

     

    用户有以下几种情况会直接访问本系统
    1 用户直接访问passport,希望登陆
    2 用户从passport_app上点击登陆按钮转过来的
    3 用户从passport_app1转到passport_app2时候,passport_app2转过来的
    4 用户直接输入访问passport_app的URL

    2 3 4 或者有referer,或者有fromurl的参数

    ====

    1 使用通行证的应用程序上面的登陆按钮全部指向下面的链接
    http://localhost/passport/login.php

    2 如果用户已经登陆了,转到5

    3 如果用户还没有登陆
      转到一个登陆页面,要包含参数:
      用户名,密码,fromurl(预处理过的refer)
      提交到login.php?op=login
     
    4 验证通过以后,设置自身的session或者cookies,

    5 根据用户http头里面的refer得到来源地址。
    5.1 如果没有来源地址则显示本passport登陆成功页面,上面列出所有的passport应用
    5.2 如果有refer,则跳回到refer的地址,即到6

    6 转到通行证应用的passport_login.php页面,传递的参数包括
        $userinfo 一个数组,包含了用户名,角色,组等其它信息,一般不需要包含密码
      $fromurl
      $verify md5($auth.$fromurl) 保证用户信息没有被篡改
    ===============================  
    7 passport_login.php
      首先检查参数有没有被改变
      然后取出参数内的user_id
     
      验证通过以后,
     
      如果user_id在系统内存不做处理
      如果不存在,则根据编码添加该用户
     
      最后设置自己的session/cookies,然后跳转到fromurl
     
      ======
     
      通行证的密匙,可以自行填写英文,可包含任何字母及数字,长度大于 10 字节

     

     

    -------

    代码如下

    session_start();

    $username = "";
    $password = "";
    $loginerror = "";
    $fromurl = '';

    if(isset($_GET['fromurl']) && trim($_GET['fromurl'])!= '') {
     $fromurl = $_GET['fromurl'];
    }else if(isset($_SERVER['HTTP_REFERER']) && trim($_SERVER['HTTP_REFERER'])!= '') {
     $fromurl = $_SERVER['HTTP_REFERER'];
    }
       
    //防止同一个服务器装了多个upassport互相干扰
    $key = md5(DB_DATABASE.DB_USER.DB_PASSWORD);
    if(!isset($_SESSION['passport_app'])) {
       unset($_SESSION['u']);
       $_SESSION['passport_app'] = $key;
       include('themes/'.THEME.'/login.html');
       exit;
    }else if($_SESSION['passport_app'] != $key) {
       unset($_SESSION['u']);
       $_SESSION['passport_app'] = $key;     
       include('themes/'.THEME.'/login.html');
       exit;  
    }

       
    if (isset($_POST['op'])&&trim($_POST['op'])=='dologin') {

     $valid = 0;
     $authnum = $_POST['authnum'];
     $username = $_POST['username'];
     
     $fromurl = $_POST['fromurl'];
     

     if ($authnum && trim($_SESSION['authnum'])==$authnum && $username) {
      
      $password = $_POST['password'];
      
        $user = $db->getRow("select * from $dbutils->user where username = '$username' and password = '$password'");

      if (!empty($user) && $user['user_id']!=0) {
       $u['user_id'] = $user['user_id'];
       $u['username'] = $user['username'];
          $u['truename'] = $user['truename'];
          
          $u['group'] = $db->getRow("select ug.group_id,g.group_name from $dbutils->user_group ug,$dbutils->group g where ug.group_id = g.group_id and ug.user_id = ".$user['user_id']);
     
       $u['roles'] = $db->getAll("select ur.role_id,r.role_name,r.privileges from $dbutils->user_role ur,$dbutils->role r where ur.role_id = r.role_id and ur.user_id = ".$user['user_id']);
       
       $privileges = Array();
       foreach($u['roles'] as $role) {
        $role_privis = explode(',',$role['privileges']);
        
         foreach($role_privis as $p) {
          if(!in_array($p,$privileges)) array_push($privileges,$p);
          
         }
        
       }   
       
        $u['privileges'] = $privileges ;    
       
       $_SESSION['u'] = $u;
       
       $valid =1;

      }
         
      }
     
     if (!$valid) {
      $loginerror = '<div class="error">'."非法登陆".'</div>';
      $username = $_POST['username'];
      unset($u);
     }  
      

    }

     //用户正常跳转或者访问
     $u = isset($_SESSION['u']) ? $_SESSION['u'] : '';
     
     
      if (empty($u)) { //用户不存在,跳到登陆界面
     
       include('themes/'.THEME.'/login.html');
       exit;
      
      }else {  //用户存在,表示已经登陆过了

          if(trim($fromurl)=='') {  //没有referer,则显示默认主页,列出所有应用
            
             $t->assign('u',$u);
             $t->render('index.html', "欢迎登陆通行证",'wrap.html',true);
            
          }else {  //从别的应用转过来的,可能是上面 2 3 4,此时必有referer
              
             //根据referer的url得到当前的应用的key和完整的地址
             $passport_app = $db->GetRow("select * from $dbutils->app where INSTR('$fromurl', url)=1");
         
             $userinfo  = passport_encrypt(passport_encode($u), $passport_app['key']);
             $verify  = md5($userinfo.$fromurl.$passport_app['key']);
            
             header("Location: ".$passport_app['login_url'].
              "?userinfo=".rawurlencode($userinfo).
              "&fromurl=".rawurlencode($fromurl).
              "&verify=$verify");

          }
     
     
      }

    客户应用检验单点登陆的方法如下

    $passport_key = '1234567890';


    if($_GET['verify'] != md5($_GET['userinfo'].$_GET['fromurl'].$passport_key)) {
     exit('Illegal request');
    }


    $u = array();
    parse_str(passport_decrypt($_GET['userinfo'], $passport_key), $u);

    header("location: ".$_GET['fromurl']);

    发表于 @ 2007年06月15日 10:44:00|评论(loading...)|收藏

    新一篇: 传奇美国黑客发表文章说:不要攻击中国大陆网站 | 旧一篇: PHP集成华为企业信息机

    评论

    #xiaoyong_8000 发表于2007-06-15 16:51:56  IP: 123.116.134.*

    欢迎加入到开发民工技术讨论群!同交流同进步,qq:40214279
    #you_kind 发表于2007-06-15 17:00:09  IP: 61.172.241.*
    呼呼 这个我们公司里已经用了1年多了
    #roblove 发表于2007-06-15 18:25:32  IP: 222.209.208.*
    #XCL6996 发表于2007-06-16 10:41:54  IP: 125.62.23.*
    顶!学习
    #gzw323 发表于2007-06-16 12:10:19  IP: 220.205.159.*
    http://www.myidc.info
    #hope1983 发表于2007-06-16 23:25:54  IP: 58.63.92.*
    典型的简单问题复杂化
    #Sunjuzheng 发表于2007-06-16 23:36:44  IP: 222.187.151.*
    你知道 Ailiss.com 吗?
    #zdm111 发表于2007-06-17 19:04:53  IP: 219.239.227.*
    cookie跨域怎么弄的
    #danny_xcz 发表于2007-06-18 08:15:25  IP: 222.186.123.*
    不依赖于cookie跨域,主要依赖你在单点登陆服务器上是否登陆了,并且保留登陆的记号(使用session),
    当然也可以用cookie跨域加快访问的速度和减少对单点认证服务器的访问压力。
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 纯月