引:这边客户反映网站后台无法登陆,前端正常登录
一、最初解决办法
办法一
凭借多年的经验,第一时间会想到的就是discuz
默认的安全配置问题,于是去修改config_global.php
文件中$_config['admincp']['checkip'] = 1;
这个值,将其修改为0,这样discuz登录管理后台时就不会进行IP验证。
办法二
修改$_config'admincp' = 0;后发现还是未生效,登录依然失败,那么能想到的就是禁用了这个IP导致无法登陆,那么这个问题的解决方法其实更加简单,首先就是进入数据库之后,在 pre_common_setting
表中搜索 skey
为 adminipaccess
,然后删除svalue
中的值就搞定了。
办法三
这边两个法子都用了,还是没有任何反应,想想是不是管理密码记错了,于是登录前台测试,正常登录,提示新手上路
欢迎您(这里留个坑),发现账号密码没有任何问题,可以进行登录。
这里账号其实为admin,这边尽量为了把当时的情况反映出来。
二、分析其他原因
1.浏览器问题
可能是浏览器缓存或者是浏览器问题,于是清除缓存和更换浏览器无解。
2.服务器问题
服务器问题,设想一下,可能是php版本或者是Nginx服务器问题,于是这边检查一下同服务器的其他dz站点,没有任何问题,重启php和Nginx也无法得到解决
3.木马或者防火墙等安全软件
没办法,只能看看是不是当前程序被木马了,篡改了文件什么的。于是这边查看了一下文件夹和文件的时间没有问题。或者是服务器有安全软件防火墙,都检查了一遍,没有任何相关文件。
三、最终解决办法
能搜索的都查询了一遍,千篇一律,都是转载和抄袭,还有就是很古老的答案。于是我这边就想,dz后台究竟是怎么样一个登陆机制在里面?
1.admin.php
入口
discuz
是多入口mvc
架构的程序,后台登录使用的就是admin.php
作为入口然后根据不同的action
进入不同的source/admincp/admincp_$action.php
。
这边主要涉及登录进入的是admincp_login.php
文件,其中登录提交参数的地址为admin.php
,并且参数中用户名为admin_username
,这个也可以直接在浏览器审查元素得到。
2.函数check_user_login
得到这个参数有什么用?
我们全局搜索一下,发现这个在一个函数中发现了提交验证。
跟踪一下代码
function check_user_login() {
global $_G;
$admin_username = isset($_POST['admin_username']) ? trim($_POST['admin_username']) : '';
if($admin_username != '') {
require_once libfile('function/member');
if(logincheck($_POST['admin_username'])) {
if((empty($_POST['admin_questionid']) || empty($_POST['admin_answer'])) && ($_G['config']['admincp']['forcesecques'] || $_G['group']['forcesecques'])) {
$this->do_user_login();
}
$result = userlogin($_POST['admin_username'], $_POST['admin_password'], $_POST['admin_questionid'], $_POST['admin_answer'], 'username', $this->core->var['clientip']);
if($result['status'] == 1) {
$cpgroupid = C::t('common_admincp_member')->fetch($result['member']['uid']);
$cpgroupid = $cpgroupid['uid'];
//这里是验证最重要的一步
//$result这个变量可以打印出来自己看看
if($cpgroupid || $this->checkfounder($result['member'])) {
C::t('common_admincp_session')->insert(array(
'uid' =>$result['member']['uid'],
'adminid' =>$result['member']['adminid'],
'panel' =>$this->panel,
'dateline' => TIMESTAMP,
'ip' => $this->core->var['clientip'],
'errorcount' => -1), false, true);
setloginstatus($result['member'], 0);
dheader('Location: '.ADMINSCRIPT.'?'.cpurl('url', array('sid')));
} else {
$this->cpaccess = -2;
}
//验证结束
} else {
loginfailed($_POST['admin_username']);
}
} else {
$this->cpaccess = -4;
}
}
}
3.函数checkfounder
当前函数中,最重要的其实是这一步。
这里发现还有一个函数,来进行验证是否写入session,这一步打印了一下,发现居然是false
这就很奇怪了,怎么会这样呢?
于是继续跟踪代码,找到函数
function checkfounder($user) {
$founders = str_replace(' ', '', $this->cpsetting['founder']);
var_dump($user);//打印$user
if(!$user['uid'] || $user['groupid'] != 1 || $user['adminid'] != 1) {
return false;
} elseif(empty($founders)) {
return true;
} elseif(strexists(",$founders,", ",$user[uid],")) {
return true;
} elseif(!is_numeric($user['username']) && strexists(",$founders,", ",$user[username],")) {
return true;
} else {
return FALSE;
}
}
估计看到这个函数的小伙伴就发现了端倪。我们打印了一下$user
,发现$user
有几个重要的参数,uid、groupid、adminid
,这三个值其中groupid并不等于1,它等于10,于是导致这个三个或判断一个为true
整体为true
。
四、解决
知道原因以后要解决这个问题,于是找到数据库,pre_common_member
,修改admin 的 groupid为1,1代表为管理员。
尝试登陆
完美解决~~
文章不错支持一下吧