UCHome登陆验证机制分析
1、登陆详解:
A:用户填好登录表单之后数据被提交给source\do_login.php 处理
B:在do_login.php中下面这些语句接收传递来的用户名密码与cookie生效时间
view sourceprint?
1. $password = $_POST['password'];
2.$username = trim($_POST['username']);
3.$cookietime = intval($_POST['cookietime']);
C:然后验证用户提交来的用户名以及密码的正确性,不正确则跳转并提示登录失败
view sourceprint?
1.//同步获取用户源
2. if(!$passport = getpassport($username, $password)) {
3. showmessage('login_failure_please_re_login', 'do.php?ac='.$_SCONFIG['login_action']);
4. }
注意:这里验证用户名与密码的正确性是通过getpassport()函数里面调用uc_client在Ucenter用户中心数据库中查询的
D:若验证通过之后,再将获取到得用户账户信息赋给setarr变量数组
view sourceprint?
1.$setarr = array(
2. 'uid' => $passport['uid'],
3. 'username' => addslashes($passport['username']),
4. 'password' => md5("$passport[uid]|$_SGLOBAL[timestamp]")//本地密码随机生成
5. );
E:查询uchome的数据库看该用户信息是否存在于Uchome数据库中,不存在的话,则将从Ucenter中查询到的用户数据写入到uchome的member表中,存在则将member中的密码替换掉从Ucenter中查询出来的密码,存入setarr变量数组中。
view sourceprint?
01.//检索当前用户
02. $query = $_SGLOBAL['db']->query("SELECT password FROM ".tname('member')." WHERE uid='$setarr[uid]'");
03. if($value = $_SGLOBAL['db']->fetch_array($query)) {
04. //把ucenter中的用户密码替换成UChome中member表中的密码
05. $setarr['password'] = addslashes($value['password']);
06. } else {
07. //更新本地用户库
08. inserttable('member', $setarr, 0, true);
09. }
F:将用户登录信息写入到Uchome的session表中
Insertsession函数在source\function_space.php中定义
其主要功能为a:清除session表中的某个用户的记录b:获得用户的IP以及是否使用隐身道具c: 将setarr变量数组中的数据插入到session表中。d:更新统计数数据等
G:将用户名与密码加密写入cookie中
view sourceprint?
1.//设置cookie
2. ssetcookie('auth', authcode("$setarr[password]\t$setarr[uid]", 'ENCODE'), $cookietime);
3. ssetcookie('loginuser', $passport['username'], 31536000);
4. ssetcookie('_refer', '');
2:验证部分
判断当前用户登录状态是通过source\function_common.php中的checkauth函数实现的
下面就来分析这个函数
view sourceprint?
01.function checkauth() {
02. global $_SGLOBAL, $_SC, $_SCONFIG, $_SCOOKIE, $_SN;
03.
04. if($_SGLOBAL['mobile'] && $_GET['m_auth']) $_SCOOKIE['auth'] = $_GET['m_auth'];
05. if($_SCOOKIE['auth']) {
06. @list($password, $uid) = explode("\t", authcode($_SCOOKIE['auth'], 'DECODE'));
07. $_SGLOBAL['supe_uid'] = intval($uid);
08. if($password && $_SGLOBAL['supe_uid']) {
09. //从session表中获取ID为$_SGLOBAL[supe_uid]的session数据
10. $query = $_SGLOBAL['db']->query("SELECT * FROM ".tname('session')." WHERE uid='$_SGLOBAL[supe_uid]'");
11. //若session表中有该用户的数据
12. if($member = $_SGLOBAL['db']->fetch_array($query)) {
13. //判断session表中的密码和cookie中的密码是否相等
14. if($member['password'] == $password) {
15. $_SGLOBAL['supe_username'] = addslashes($member['username']);
16. $_SGLOBAL['session'] = $member;
17. } else {
18. $_SGLOBAL['supe_uid'] = 0;
19. }
20. //若session表中么有有该用户的数据,则从用户数据表member中查询该ID得用户数据
21. } else {
22. $query = $_SGLOBAL['db']->query("SELECT * FROM ".tname('member')." WHERE uid='$_SGLOBAL[supe_uid]'");
23. if($member = $_SGLOBAL['db']->fetch_array($query)) {
24. if($member['password'] == $password) {
25. $_SGLOBAL['supe_username'] = addslashes($member['username']);
26. $session = array('uid' => $_SGLOBAL['supe_uid'], 'username' => $_SGLOBAL['supe_username'], 'password' => $password);
27. include_once(S_ROOT.'./source/function_space.php');
28. insertsession($session);//登录
29. } else {
30. $_SGLOBAL['supe_uid'] = 0;
31. }
32. } else {
33. $_SGLOBAL['supe_uid'] = 0;
34. }
35. }
36. }
37. }
38. if(empty($_SGLOBAL['supe_uid'])) {
39. clearcookie();
40. } else {
41. $_SGLOBAL['username'] = $member['username'];
42. }
43.}
A:判断$_cookie[auth]是否存在,若不存在则不进行任何处理,并清除所有cookie
B:从cookie中反解出用户名跟密码信息
注意:这里说的密码以及上面说的将密码加密进cookie中的密码并不是用户的真实密码,而是经过md5双重加密并且salt处理后的密码
C:从session数据表中取出用户ID为$_SGLOBAL[supe_uid]的用户信息,若该记录存在则执行下面的操作,否则执行D操作(直接查询用户数据库)如果取出来的密码与cookie中的密码相等,那么判定为登录成功将数据写入到$_SGLOBAL['session']数组否则判定为登录失败,清除所有cookie
D:在C步时,若在session表中没有该用户的数据则,在用户数据表member中查询该ID得用户数据,看cookie中的密码是否与数据库中的密码一样,如果一样则登录成功,并将用户数据写入到session表中保持用户的登录状态,否则登录失败
上面无论是用session表来判定登录状态还是用member表来判定登录状态,都会影响到一个变量,那就是$_SGLOBAL['supe_uid'],在程序处理的时候,用户登录与否一般要用到得变量就是$_SGLOBAL['supe_uid']。