[原创]uchome登陆机制分析

嘿嘿,我的独立博客对应的地址:http://imzc.net/show-102-1.html


uchome_ROOT/为uchome的根目录
第一步:
定位到uchome_ROOT/source/do_login.php,找到如下函数:

PHP代码
  1. //同步获取用户源  
  2. if(!$passport = getpassport($username$password)) {  
  3.     showmessage('login_failure_please_re_login''do.php?ac='.$_SCONFIG['login_action']);  
  4. }  

上示函数便是登陆的第一步处理函数,再次定位:

uchome_ROOT/source/function_common.php,找到如下函数:

 

PHP代码
  1. //获取用户数据  
  2. function getpassport($username$password) {  
  3.     global $_SGLOBAL$_SC;  
  4.   
  5.     $passport = array();  
  6.     if(!@include_once S_ROOT.'./uc_client/client.php') {  
  7.         showmessage('system_error');  
  8.     }  
  9.   
  10.     $ucresult = uc_user_login($username$password);  
  11.     if($ucresult[0] > 0) {  
  12.         $passport['uid'] = $ucresult[0];  
  13.         $passport['username'] = $ucresult[1];  
  14.         $passport['email'] = $ucresult[3];  
  15.     }  
  16.     return $passport;  
  17. }  

至此,我们可以发现现在开始和uc_client相关函数关联了.我们进入uc_client文件夹,开始分析,定位至:uchome_ROOT/uc_client/client.php

 

 

PHP代码
  1. /** 
  2.  * 用户登陆检查 
  3.  * 
  4.  * @param string $username  用户名/uid 
  5.  * @param string $password  密码 
  6.  * @param int $isuid        是否为uid 
  7.  * @param int $checkques    是否使用检查安全问答 
  8.  * @param int $questionid   安全提问 
  9.  * @param string $answer    安全提问答案 
  10.  * @return array (uid/status, username, password, email) 
  11.     数组第一项 
  12.     1  : 成功 
  13.     -1 : 用户不存在,或者被删除 
  14.     -2 : 密码错 
  15. */  
  16. function uc_user_login($username$password$isuid = 0, $checkques = 0, $questionid = ''$answer = '') {  
  17.     $isuid = intval($isuid);  
  18.     //define('UC_API_FUNC', UC_CONNECT == 'mysql' ? 'uc_api_mysql' : 'uc_api_post');  
  19.     $return = call_user_func(UC_API_FUNC, 'user''login'array('username'=>$username'password'=>$password'isuid'=>$isuid'checkques'=>$checkques'questionid'=>$questionid'answer'=>$answer));  
  20.     return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return);  
  21. }  

因为是mysql,故,UC_API_FUNC的值为uc_api_mysql,通过call_user_func()函数,将参数传给uc_api_mysql(),下面进入最关键的函数了:

 

uchome_ROOT/uc_client/client.php => uc_api_mysql()

PHP代码
  1. /** 
  2.  * MYSQL 方式取指定的模块和动作的数据 
  3.  * 
  4.  * @param string $model     请求的模块 
  5.  * @param string $action    请求的动作 
  6.  * @param string $args      参数(会加密的方式传送) 
  7.  * @return mix 
  8.  */  
  9.   
  10. function uc_api_mysql($model$action$args=array()) {  
  11.     //$model = 'user',$action= 'login',  
  12.     //$args = Array ( [username] => test2 [password] => test [isuid] => 0 [checkques] => 0 [questionid] => [answer] => )   
  13.     global $uc_controls;  
  14.     if(empty($uc_controls[$model])) {  
  15.         //UC_ROOT uc_client/  
  16.         include_once UC_ROOT.'./lib/db.class.php';  
  17.         include_once UC_ROOT.'./model/base.php';  
  18.         include_once UC_ROOT."./control/$model.php";  
  19.         eval("\$uc_controls['$model'] = new {$model}control();");  
  20.         //uc_client/control/user.php,usercontrol()类(继承至base基类)实例化  
  21.     }  
  22.     if($action{0} != '_') {  
  23.         $args = uc_addslashes($args, 1, TRUE);  
  24.         $action = 'on'.$action;//onlogin,usercontrol()中的方法,可以考虑改造此函数以实现预定功能  
  25.         $uc_controls[$model]->input = $args;//base.php,base基类的方法  
  26.         //return Array ( [0] => 3 [1] => test2 [2] => test [3] => test@12.com [4] => 0 )   
  27.           
  28.         return $uc_controls[$model]->$action($args);//返回预定数组,供调用函数分析  
  29.     } else {  
  30.         return '';  
  31.     }  
  32. }  
我们看看usercontrol类的onlogin()方法:

uchome_ROOT/uc_client/control/user.php

PHP代码
  1. //note public 外部接口 登陆接口  
  2. function onlogin() {  
  3.     $this->init_input();  
  4.     $isuid = $this->input('isuid');  
  5.     $username = $this->input('username');  
  6.     $password = $this->input('password');  
  7.     $checkques = $this->input('checkques');  
  8.     $questionid = $this->input('questionid');  
  9.     $answer = $this->input('answer');  
  10.     if($isuid) {  
  11.         $user = $_ENV['user']->get_user_by_uid($username);  
  12.     } else {  
  13.         $user = $_ENV['user']->get_user_by_username($username);  
  14.     }  
  15.   //这部分即可改动
  16.     $passwordmd5 = preg_match('/^\w{32}$/'$password) ? $password : md5($password);  
  17.     //note 用户名不存在  
  18.     if(empty($user)) {  
  19.         $status = -1;  
  20.     } elseif($user['password'] != md5($passwordmd5.$user['salt'])) {  
  21.         $status = -2;  
  22.     } elseif($checkques && $user['secques'] != '' && $user['secques'] != $_ENV['user']->quescrypt($questionid$answer)) {  
  23.         $status = -3;  
  24.     } else {  
  25.         $status = $user['uid'];  
  26.     }  
  27.     $merge = $status != -1 && !$isuid && $_ENV['user']->check_mergeuser($username) ? 1 : 0;  
  28.     return array($status$user['username'], $password$user['email'], $merge);  
  29. }  
可以改成如下形式:

PHP代码
  1. //note public 外部接口 登陆接  
  2.     function onlogin($type='myself') {  
  3.         $this->init_input();  
  4.         $isuid = $this->input('isuid');  
  5.         $username = $this->input('username');  
  6.         $password = $this->input('password');  
  7.         $checkques = $this->input('checkques');  
  8.         $questionid = $this->input('questionid');  
  9.         $answer = $this->input('answer');  
  10.         if($isuid) {  
  11.             $user = $_ENV['user']->get_user_by_uid($username);  
  12.         } else {  
  13.             $user = $_ENV['user']->get_user_by_username($username);  
  14.         }  
  15.   
  16.         $passwordmd5 = preg_match('/^\w{32}$/'$password) ? $password : md5($password);  
  17.   
  18.         $type='myself';  
  19.         if($type=='myself')  
  20.         {  
  21.             echo '$password:'.$password.'<br>';  
  22.             $testmd5 = md5('test');//假设数据库中保持的所有的密码为test  
  23. //          print_r($passwordmd5);  
  24. //          print_r($user);  
  25.             //note 用户名不存在  
  26.               
  27.             if(emptyempty($user)) {  
  28.                 $status = -1;  
  29.             } elseif($user['password'] != $passwordmd5) {  
  30.                 $status = -2;  
  31.             } elseif($checkques && $user['secques'] != '' && $user['secques'] != $_ENV['user']->quescrypt($questionid$answer)) {  
  32.                 $status = -3;  
  33.             } else {  
  34.                 $status = $user['uid'];  
  35.             }  
  36. //          echo '<br>$statusz:'.$status.'<br>';  
  37. //          die();  
  38.         }else{  
  39.             if(emptyempty($user)) {  
  40.                 $status = -1;  
  41.             } elseif($user['password'] != md5($passwordmd5.$user['salt'])) {  
  42.                 $status = -2;  
  43.             } elseif($checkques && $user['secques'] != '' && $user['secques'] != $_ENV['user']->quescrypt($questionid$answer)) {  
  44.                 $status = -3;  
  45.             } else {  
  46.                 $status = $user['uid'];  
  47.             }  
  48.         }  
  49.         $merge = $status != -1 && !$isuid && $_ENV['user']->check_mergeuser($username) ? 1 : 0;  
  50.         return array($status$user['username'], $password$user['email'], $merge);  
  51.     }  

至此,我们可以更改uchome默认的认证方式了,如果这里更改了,以后相关的也需要作出更改,这个就留下大家自己去跟踪调试了.

tips:

uchome_ROOT/uc_client/model/user.php下还有一个check_login(),这个函数暂时没有找到调用的地方.

PHP代码
  1. function check_login($username$password, &$user) {  
  2.     $user = $this->get_user_by_username($username); 
  3.     if(empty($user['username'])) {  
  4.         return -1;  
  5.     } elseif($user['password'] != md5(md5($password).$user['salt'])) {  
  6.         return -2;  
  7.     }  
  8.     return $user['uid'];  
  9. }  

eclipsePDT还是不错的,可以试试这个IDE.


 

 

posted @ 2009-08-13 19:15  O(∩_∩)O川zc  阅读(1135)  评论(1编辑  收藏  举报