discuz登录流程解析,最近在研究,Ucenter的同步登陆机制,就先从discuz的登录开始了
1.form表单提交
member.php?mod=logging&action=login&loginsubmit=yes&handlekey=login&loginhash=Lm137&inajax=1
处理脚本 source/module/member/member_logging.php
$ctl_obj = new logging_ctl();//初始化登陆对象,source\class\class_member.php=>class logging_ctl$ctl_obj->setting = $_G['setting'];$method = 'on_'.$_GET['action'];//$method='on_login';$ctl_obj->template = 'member/login';$ctl_obj->$method();//调用source\class\class_member.php=>on_login()
下面对source\class\class_member.php的on_login进行分析
2.source\class\class_member.php
on_login函数太长,只贴出其核心部分,该函数也是登录过程中的核心函数,通过 userlogin(uc_client\control\user.php)进行数据分析,并对返回结果$result进行分析处理,返回结果$result['status']>0时,显示登陆成功,setloginstatus进行登录状态记录
$result = userlogin($_GET['username'], $_GET['password'], $_GET['questionid'], $_GET['answer'], $this->setting['autoidselect'] ? 'auto' : $_GET['loginfield'], $_G['clientip']);//95行左右,userlogin为核心处理函数,来至uc_client\client.php//根据$result['status']返回值进行处理············if($result['status'] > 0) //当$result['status']>0时,为登陆成功setloginstatus($result['member'], $_GET['cookietime'] ? 2592000 : 0);//记录登录状态,完成登录动作
下面对uc_client\client.php的uc_user_login进行分析
3.uc_client\client.php
函数uc_user_login通过call_user_func调用uc_client\control\user.php的onlogin函数
function uc_user_login($username, $password, $isuid = 0, $checkques = 0, $questionid = '', $answer = '', $ip = '') {$isuid = intval($isuid);$return = call_user_func(UC_API_FUNC, 'user', 'login', array('username'=>$username, 'password'=>$password, 'isuid'=>$isuid, 'checkques'=>$checkques, 'questionid'=>$questionid, 'answer'=>$answer, 'ip' => $ip));//UC_API_FUNC= uc_api_mysql,通过call_user_func回调调用uc_api_mysql,进行传参数,通过uc_api_mysql引入uc_client\control\user.php的onlogin函数return UC_CONNECT == 'mysql' ? $return : uc_unserialize($return);}...................function uc_api_mysql($model, $action, $args=array()) {global $uc_controls;if(empty($uc_controls[$model])) {if(function_exists("mysql_connect")) {include_once UC_ROOT.'./lib/db.class.php';} else {include_once UC_ROOT.'./lib/dbi.class.php';}include_once UC_ROOT.'./model/base.php';include_once UC_ROOT."./control/$model.php";//引入uc_client\control\user.phpeval("\$uc_controls['$model'] = new {$model}control();");}if($action{0} != '_') {$args = uc_addslashes($args, 1, TRUE);$action = 'on'.$action;$uc_controls[$model]->input = $args;return $uc_controls[$model]->$action($args);//调用uc_client\control\user.php的onlogin函数传参数} else {return '';}}
4.uc_client\control\user.php
onlogin函数对数据进行分析,返回结果,回第2步中source\class\class_member.php的
function onlogin() {$this->init_input();$isuid = $this->input('isuid');$username = $this->input('username');$password = $this->input('password');$checkques = $this->input('checkques');$questionid = $this->input('questionid');$answer = $this->input('answer');$ip = $this->input('ip');$this->settings['login_failedtime'] = is_null($this->settings['login_failedtime']) ? 5 : $this->settings['login_failedtime'];if($ip && $this->settings['login_failedtime'] && !$loginperm = $_ENV['user']->can_do_login($username, $ip)) {$status = -4;return array($status, '', $password, '', 0);}if($isuid == 1) {$user = $_ENV['user']->get_user_by_uid($username);} elseif($isuid == 2) {$user = $_ENV['user']->get_user_by_email($username);} else {$user = $_ENV['user']->get_user_by_username($username);}$passwordmd5 = preg_match('/^\w{32}$/', $password) ? $password : md5($password);if(empty($user)) {$status = -1;} elseif($user['password'] != md5($passwordmd5.$user['salt'])) {$status = -2;} elseif($checkques && $user['secques'] != $_ENV['user']->quescrypt($questionid, $answer)) {$status = -3;} else {$status = $user['uid'];}if($ip && $this->settings['login_failedtime'] && $status <= 0) {$_ENV['user']->loginfailed($username, $ip);}$merge = $status != -1 && !$isuid && $_ENV['user']->check_mergeuser($username) ? 1 : 0;return array($status, $user['username'], $password, $user['email'], $merge);}
登录解析完成完成

本文详细解析了Discuz登录流程,包括form表单提交、关键处理函数userlogin的工作原理及uc_user_login函数如何通过调用onlogin实现同步登录。
683

被折叠的 条评论
为什么被折叠?



