标题: ZF结合DZ和Dede的通行证
fidy
新手上路
Rank: 1



UID 87
精华 1
积分 10
帖子 15
翻译 0
原创 1
阅读权限 10
注册 2007-6-18
状态 离线
发表于 2008-6-18 21:44  资料  短消息  加为好友  添加 fidy 为MSN好友 通过MSN和 fidy 交谈
ZF结合DZ和Dede的通行证

用户基本数据保存在ZF程序的User表中,DZ和Dede的用户表不再作认证用:
先把DZ和Dede提供的通行证函数简单封装一下:
Fidy_Passport_Discuz.php

PHP代码如下:

<?php

class Fidy_Passport_Discuz {
        
        protected 
$key null;
        protected 
$apiUrl null;
        protected 
$info null;
        protected 
$action null;
        protected 
$forword null;
        protected 
$auth null;
        
        public function 
__construct($config$info$forword){
                
$this->key $config->key;
                
$this->apiUrl $config->apiUrl;
                
$this->info $info;
                
$this->forword $forword;
                
$this->auth $this->passport_encrypt($this->passport_encode($this->info), $this->key);
        }

        protected function 
passport_encrypt($txt$key) {

                
// 使用随机数发生器产生 0~32000 的值并 MD5()
                
srand((double)microtime() * 1000000);
                
$encrypt_key md5(rand(032000));

                
// 变量初始化
                
$ctr 0;
                
$tmp '';

                
// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
                
for($i 0$i strlen($txt); $i++) {
                        
// 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
                        
$ctr $ctr == strlen($encrypt_key) ? $ctr;
                        
// $tmp 字串在末尾增加两位,其第一位内容为 $encrypt_key 的第 $ctr 位,
                        // 第二位内容为 $txt 的第 $i 位与 $encrypt_key 的 $ctr 位取异或。然后 $ctr = $ctr + 1
                        
$tmp .= $encrypt_key[$ctr].($txt[$i] ^ $encrypt_key[$ctr++]);
                }

                
// 返回结果,结果为 passport_key() 函数返回值的 base64 编码结果
                
return base64_encode($this->passport_key($tmp$key));

        }

        
/**
        * Passport 解密函数
        *
        * @param                string                加密后的字串
        * @param                string                私有密匙(用于解密和加密)
        *
        * @return        string                字串经过私有密匙解密后的结果
        */
        
protected function passport_decrypt($txt$key) {

                
// $txt 的结果为加密后的字串经过 base64 解码,然后与私有密匙一起,
                // 经过 passport_key() 函数处理后的返回值
                
$txt $this->passport_key(base64_decode($txt), $key);

                
// 变量初始化
                
$tmp '';

                
// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
                
for ($i 0$i strlen($txt); $i++) {
                        
// $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
                        // 与 $txt 的第 $i + 1 位取异或。然后 $i = $i + 1
                        
$tmp .= $txt[$i] ^ $txt[++$i];
                }

                
// 返回 $tmp 的值作为结果
                
return $tmp;

        }

        
/**
        * Passport 密匙处理函数
        *
        * @param                string                待加密或待解密的字串
        * @param                string                私有密匙(用于解密和加密)
        *
        * @return        string                处理后的密匙
        */
        
protected function passport_key($txt$encrypt_key) {

                
// 将 $encrypt_key 赋为 $encrypt_key 经 md5() 后的值
                
$encrypt_key md5($encrypt_key);

                
// 变量初始化
                
$ctr 0;
                
$tmp '';

                
// for 循环,$i 为从 0 开始,到小于 $txt 字串长度的整数
                
for($i 0$i strlen($txt); $i++) {
                        
// 如果 $ctr = $encrypt_key 的长度,则 $ctr 清零
                        
$ctr $ctr == strlen($encrypt_key) ? $ctr;
                        
// $tmp 字串在末尾增加一位,其内容为 $txt 的第 $i 位,
                        // 与 $encrypt_key 的第 $ctr + 1 位取异或。然后 $ctr = $ctr + 1
                        
$tmp .= $txt[$i] ^ $encrypt_key[$ctr++];
                }

                
// 返回 $tmp 的值作为结果
                
return $tmp;

        }

        
/**
        * Passport 信息(数组)编码函数
        *
        * @param                array                待编码的数组
        *
        * @return        string                数组经编码后的字串
        */




        
protected function passport_encode($array) {

                
// 数组变量初始化
                
$arrayenc = array();

                
// 遍历数组 $array,其中 $key 为当前元素的下标,$val 为其对应的值
                
foreach($array as $key => $val) {
                        
// $arrayenc 数组增加一个元素,其内容为 "$key=经过 urlencode() 后的 $val 值"
                        
$arrayenc[] = $key.'='.urlencode($val);
                }

                
// 返回以 "&" 连接的 $arrayenc 的值(implode),例如 $arrayenc = array('aa', 'bb', 'cc', 'dd'),
                // 则 implode('&', $arrayenc) 后的结果为 ”aa&bb&cc&dd"
                
return implode('&'$arrayenc);

        }
        
        
        
        
        protected function 
getAuth(){
                return 
$this->auth;
        }
        
        protected function 
getVerify(){
                return 
md5($this->action.$this->getAuth().$this->forword.$this->key);
        }
        
        protected function 
getAction(){
                return 
$this->action;
        }
        
        protected function 
generateRequest(){
                return 
$this->apiUrl.
                    
"?action=".$this->getAction().
                    
"&auth=".urlencode($this->getAuth()).   
                                        
"&forward=".urlencode($this->forword).            
                    
"&verify=".$this->getVerify();
        }
        
        public function 
login(){
                
$this->action "login";
                return 
$this->generateRequest();
        }
        
        public function 
logout(){
                
$this->action "logout";
                return 
$this->generateRequest();
        }
        
        public function 
register(){
                
$this->action "login";
                return 
$this->generateRequest();
        }
        
}
?>


Fidy_Passport_Dede.php

PHP代码如下:

<?php

class Fidy_Passport_Dede {

        
        private 
$cfg_cookie_encode "";
        
        
//Cookie主域名(用 "abc.com" 形式,不要加主机名,本地域名留空%>
        
        
private $domain "";
        
        private 
$DedeAPI_Url "";
        
        public function 
__construct($config){
                
$this->cfg_cookie_encode $config->cookieKey;
                
$this->DedeAPI_Url $config->apiUrl;
                
$this->domain $config->cookieDomain;
        }
        
        
//----------------------------------
        //第三方系统与Dedecms系统同步注册、登录、更改密码、退出接口函数
        //SynchDedeCms($userid,$action,$exptime='36000')
        //参数说明
        /*-------------------------
        $userid          用户登录的用户名,必须
        $action          动作,必须,选项为:reg edit login exit test(测试用户ID是否存在)
        $exptime='36000' cookie保存时间,单位为秒
        返回值:
        返回字串前三位为OK!表示操作成功
        返回其它则是错误提示
        --------------------------*/
        
public function SynchDedeCms($userid,$action,$exptime=36000){
                
$cpath '/';
                 
                
$keys = Array('userid','action','exptime');
                
$querystr '';
                  foreach(
$keys as $v){
                           if(!empty(
$v)) $querystr .= $v.'='.urlencode($v).'&';
                 }
                
$signstr substr(md5($userid.$this->cfg_cookie_encode),0,24);
                
$querystr .= "signstr=$signstr";
                
$this->DedeAPI_Url $this->DedeAPI_Url."?rmdata=".base64_encode($querystr);
           
            
$rcdata file_get_contents($this->DedeAPI_Url);
           
           
           if(
substr($rcdata,0,3)=='OK!'){
                     
$okdata ereg_replace("^OK!","",$rcdata);
                     if(
$okdata!=""){
                             
$headerStr trim($okdata);
                             
$this->PutCookie("DedeUserID",$headerStr,$exptime,$cpath,$this->domain);
                             
$this->PutCookie("DedeUserIDckMd5",substr(md5($this->cfg_cookie_encode.$headerStr),0,16),$exptime,$cpath,$this->domain);
                     }
                     return 
'OK';
                  }else{
                           return 
$rcdata;
                }
        }

        
//按默认参数设置一个Cookie
        
protected function PutCookie($key,$value,$exptime,$pa='/',$dm=''){
                
setcookie($key,$value,time()+$exptime,$pa,$dm);
                
setcookie($key.'ckMd5',substr(md5($this->cfg_cookie_encode.$value),0,16),time()+$exptime,$pa,$dm);
        }
}


?>



顶部
fidy
新手上路
Rank: 1



UID 87
精华 1
积分 10
帖子 15
翻译 0
原创 1
阅读权限 10
注册 2007-6-18
状态 离线
发表于 2008-6-18 21:48  资料  短消息  加为好友  添加 fidy 为MSN好友 通过MSN和 fidy 交谈
配置文件举例:

<passport>
            <discuz>
                    <key>@#$%^&***adf</key>
                                <apiUrl>http://www.example.local/bbs/api/passport.php</apiUrl>
            </discuz>
            <dede>
                                <cookieKey>#$#%JJ&^%</cookieKey>
                                <apiUrl>http://www.example.local/cms/mem ... deremote_new.php</apiUrl>
                                <cookieDomain>example.local</cookieDomain>
                        </dede>
              </passport>

ZF中应用举例:

PHP代码如下:
class IndexController extends Zend_Controller_Action
{

    public function 
loginAction(){
            if(
$this->auth->getIdentity()){
                        
$this->_redirect("/");
                }else{
                        if(
$this->_request->isPost()){
                                
$filter = new Zend_Filter_StripTags();
                                
$userName $filter->filter($this->_request->getPost('username'));
                                
$password $this->_request->getPost('password');
                                
$forword $this->_request->getPost('forword');
                                if (empty(
$userName) || empty($password)) {
                                        
$this->view->message "请填写用户名和密码!";
                                        return;
                                }
                                
                                
$myAuthAdapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table::getDefaultAdapter(),'user','username','password','MD5(?)');
                                
$myAuthAdapter->setIdentity($userName)->setCredential($password);
                                
$result $this->auth->authenticate($myAuthAdapter);
                                
                                if(
$result->isValid()){// login success
                                       
                                        
$theUser $myAuthAdapter->getResultRowObject();
                                       
                                        
$userinfoForDZ = array('time'=>$theUser->time,'username'=>$theUser->username,'password'=>$theUser->password,'email'=>$theUser->email);
                                       
                                        
$this->auth->getStorage()->write($theUser);
                                       
                                        
$dedePassport = new Fidy_Passport_Dede($this->config->passport->dede);
                                       
                                        
$this->view->dedeResult $dedePassport->SynchDedeCms($theUser->username'login');
                                        
$discuzPassport = new Fidy_Passport_Discuz($this->config->passport->discuz$userinfoForDZ$forword);
                                        
$this->_redirect($discuzPassport->login());
                                
                                }else{
//login faild
                                        
$this->view->message "用户名或者密码错误!";
                                }
                        }else{
                                
$this->view->forward "http://www.example.local/";
                        }
                }
    }



Dede通行证的远程接口有错误,改改才能用...(适用于dede 5.1)
pp_dederemote_new.php

PHP代码如下:

<?php

require_once(dirname(__FILE__)."/../../include/config_base.php");
header("Content-Type: text/html; charset=gb2312");

$ppName "";

if(
$cfg_pp_isopen == 0){
        echo 
"系统没开启通行证功能,禁止远程调用!";
        exit();
}

$cfg_ndsql 0;

if(empty(
$rmdata)){
        echo 
"没接收到任何远程数据!";
        exit();
}

$keys = Array('userid','signstr','action');

foreach(
$keys as $v$v '';

//解码GET字符串
$rmdata base64_decode($rmdata);
$datas explode('&',$rmdata);
foreach(
$datas as $ky){
        
$nkys explode('=',$ky);
        if(
in_array($nkys[0],$keys) && isset($nkys[1])) ${$nkys[0]} = urldecode($nkys[1]);
}

$ntime time();

if(
$action!='exit'){
  
//验证证书
  
if($userid==''||!TestStringSafe($userid)){
          echo 
"用户ID为空或存在非法字符串!".$oldrmdata;
          exit();
  }
  if(
strlen($userid)>24){
          echo 
"用户ID长度不能超过24位!";
          exit();
  }
  
$testSign substr(md5($userid.$cfg_cookie_encode),0,24);
  if(
$testSign!=$signstr){
          echo 
"证书验证失败!";
          exit();
  }
}

if(
$action=='reg'){
        
Z_OpenSql();
        
$userpwd chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).mt_rand(1000,9999).chr(mt_rand(ord('A'),ord('Z')));
        
$userpwd GetEncodePwd($userpwd);
        
$loginip Z_GetIP();
        
$ppuserid $userid.$ppName;
   
   
$uname $ppuserid;
   
$inQuery1 "
          INSERT INTO `#@__member` (`userid` , `pwd` , `type` , `uname` , `membertype` , `uptime` , `exptime` ,
            `money` , `email` , `jointime` , `joinip` , `logintime` , `loginip` ,
             `c1` , `c2` , `c3` , `matt` , `guestbook` , `spaceshow` , `pageshow` , `spacestyle` ,
              `spacename` , `spaceimage` , `news` , `mybb` , `listnum` , `scores` )
    VALUES ('$ppuserid', '$userpwd', '0', '$uname', '10', '0', '0',
     '0', '', '$ntime', '$loginip', '$ntime', '$loginip',
      '0', '0', '0', '0', '0', '0', '0', '',
       '', '', '', '', '20', '1000');
         "
;
   
   
$cfg_ndsql->ExecuteNoneQuery($inQuery1);
   
   
$id $cfg_ndsql->GetLastID();
   if(
$id>0){
      
$inQuery2 "
              INSERT INTO `#@__member_perinfo` (`id`, `uname` , `sex` , `birthday` , `weight` ,`height` , `job` , `province` , `city` , `myinfo` ,
             `tel` , `oicq` , `homepage` , `showaddr` ,`address` , `fullinfo`)
       VALUES ('$id','$uname', '', '0000-00-00', '0','0', '0', '0', '0', '0' ,
        '0' , '0' , '0' ,'0','0','');
     "
;        
     
$cfg_ndsql->ExecuteNoneQuery($inQuery2);
   }
   
   
$row $cfg_ndsql->GetOne("Select ID From #@__member where userid like '{$userid}$ppName' ");
         
$ID $row['ID'];
         
Z_CloseSql();
         echo 
'OK!'.$ID;
         exit();
}
/*--------------------------------
会员登录
function __UserLogin()
---------------------------------*/
else if($action=='login'){
        
Z_OpenSql();
        
$row $cfg_ndsql->GetOne("Select ID,pwd From #@__member where userid like '{$userid}$ppName' ");
        
$loginip Z_GetIP();
        if(!
is_array($row)){
                 
$userpwd chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('A'),ord('Z'))).chr(mt_rand(ord('a'),ord('z'))).mt_rand(1000,9999).chr(mt_rand(ord('A'),ord('Z')));
           
$userpwd GetEncodePwd($userpwd);
           
$ppuserid $userid.$ppName;
                 
                 
                 
$uname $ppuserid;
   
$inQuery1 "
          INSERT INTO `#@__member` (`userid` , `pwd` , `type` , `uname` , `membertype` , `uptime` , `exptime` ,
            `money` , `email` , `jointime` , `joinip` , `logintime` , `loginip` ,
             `c1` , `c2` , `c3` , `matt` , `guestbook` , `spaceshow` , `pageshow` , `spacestyle` ,
              `spacename` , `spaceimage` , `news` , `mybb` , `listnum` , `scores` )
    VALUES ('$ppuserid', '$userpwd', '0', '$uname', '10', '0', '0',
     '0', '', '$ntime', '$loginip', '$ntime', '$loginip',
      '0', '0', '0', '0', '0', '0', '0', '',
       '', '', '', '', '20', '1000');
         "
;
   
   
$cfg_ndsql->ExecuteNoneQuery($inQuery1);
   
   
$id $cfg_ndsql->GetLastID();
   if(
$id>0){
      
$inQuery2 "
              INSERT INTO `#@__member_perinfo` (`id`, `uname` , `sex` , `birthday` , `weight` ,`height` , `job` , `province` , `city` , `myinfo` ,
             `tel` , `oicq` , `homepage` , `showaddr` ,`address` , `fullinfo`)
       VALUES ('$id','$uname', '', '0000-00-00', '0','0', '0', '0', '0', '0' ,
        '0' , '0' , '0' ,'0','0','');
     "
;        
     
$cfg_ndsql->ExecuteNoneQuery($inQuery2);
   }
     
     
     
$row $cfg_ndsql->GetOne("Select ID,pwd From #@__member where userid like '$userid' ");
        }
        
$ID $row['ID'];
        
$cfg_ndsql->ExecuteNoneQuery("update #@__member set logintime='$ntime',loginip='$loginip' where ID='$ID' ");
        
Z_CloseSql();
        echo 
'OK!'.$ID;
        exit();
}

else if(
$action=='exit'){
        echo 
'OK!0';
        exit();
}

else{
        echo 
"无法识别你的动作!";
        exit();
}

//其它功能如函数
function Z_OpenSql(){
        global 
$cfg_ndsql;
        if(!
$cfg_ndsql$cfg_ndsql = new DedeSql(false);
}
function 
Z_CloseSql(){
        global 
$cfg_ndsql;
        if(
$cfg_ndsql$cfg_ndsql->Close();
}
function 
Z_GetIP(){
        if(!empty(
$_SERVER["HTTP_CLIENT_IP"])) $cip $_SERVER["HTTP_CLIENT_IP"];
        else if(!empty(
$_SERVER["HTTP_X_FORWARDED_FOR"])) $cip $_SERVER["HTTP_X_FORWARDED_FOR"];
        else if(!empty(
$_SERVER["REMOTE_ADDR"])) $cip $_SERVER["REMOTE_ADDR"];
        else 
$cip "无法获取!";
        return 
$cip;
}
?>



顶部
yhl_amerry
新手上路
Rank: 1



UID 1230
精华 0
积分 0
帖子 27
翻译 0
原创 0
阅读权限 10
注册 2008-5-26
状态 离线
发表于 2008-8-6 14:05  资料  短消息  加为好友 
谢谢分享,收藏下...

顶部
小树叶子
新手上路
Rank: 1



UID 559
精华 0
积分 0
帖子 7
翻译 0
原创 0
阅读权限 10
注册 2007-11-14
状态 离线
发表于 2008-8-29 10:38  资料  短消息  加为好友 
多谢

顶部
 


PHPEye开源社区


当前时区 GMT+8, 现在时间是 2012-2-10 11:24

    Powered by Discuz! 5.5.0  © 2001-2007 Comsenz Inc.
Processed in 0.025537 second(s), 8 queries , Gzip enabled

清除 Cookies - 联系我们 - PHPEye开源社区 - Archiver