thinkphp,discuz同步登录问题记录
继续之前的thinkphp,discuz同步登录实现方案,部分用户在thinkphp应用中登录之后,验证,登录成功,但是用户状态并未更新,仍是未登录状态,因为判断用户登录状态的是根据discuz产生的cookie值,即$_COOKIE['C9sR_2132_auth']。所以,登录状态未更新,问题应该是在同步登录执行过后,返回的<script>….</script>虽调用了类似这样的地址:“http:///论坛域名/api/uc.php?time=1506567130&code=4b45pG%2BLreDUq2Bqfrz5zZAMxtF7pjGnBcP%2BQhvzp62oVwyIA”,去生成$_COOKIE['C9sR_2132_auth'],但并未成功生成,导致在判断登录状态时,没有通过。
检查登录状态未通过的用户,有一个共同特征:在ucenter的用户表(pre_ucenter_member)中存在对应的记录,但在discuz的用户表(pre_common_member)中没有没有对应的记录。
从以上发现可以判断,discuz产生cookie值时,验证的是自身的用户表(pre_common_member),如果没有用户对应的记录,用户对应的cookie值就不会产生。
为了保障所有用户都能成功登录,且状态得到更新,可以将表pre_ucenter_member和pre_common_member的数据进行同步,类似于在discuz中的自动激活ucenter中用户的方法。思路如下:
1)获取UCenter用户中心的所有用户:$UcUser
2)获取Discuz论坛的所有用户(已激活用户):$DzUser
3)从$UcUser中排除掉$DzUser中的用户,得到代激活的用户:$UcUser
4)遍历$UcUser,依次执行激活操作
下边给出PHP代码的具体实现过程,直接在discuz根目录新建activation.php,代码如下:
<?php define('APPTYPEID', 0); define('CURSCRIPT', 'member'); require './source/class/class_core.php'; require './config/config_ucenter.php'; $discuz = C::app(); define('CURMODULE', $mod); $discuz->init(); require libfile('function/member'); require libfile('class/member'); $UcUser = array(); $start = $_GET['start']; //从uid等于$start的记录开始 $end = $_GET['end'];//到uid等于$end的记录结束 $map = 'WHERE `uid` > '.$start.' and `uid` <='.$end.' ORDER BY `uid` ASC'; //获取UC用户中心的用户 $pquery = DB::query('select uid,username,email from bbs.bbs_ucenter_members ' . $map); while ($pquery && $post = DB::fetch($pquery)) { $UcUser[$post['uid']] = $post; } //获取Discuz中已激活的用户 $pquery = DB::query('select uid from bbs.bbs_common_member ' . $map); while ($pquery && $post = DB::fetch($pquery)) { //循环排除已激活的用户 unset($UcUser[$post['uid']]); } $init_arr = array(0, 0, 0, 0, 0, 0, 0, 0, 0); //用户相关杂项 $groupid = 10; //用户组ID foreach ($UcUser as $uid => $row) { //执行Discuz自带的激活操作 C::t('common_member')->insert($uid, $row['username'], md5(random(10)), $row['email'], $_G['clientip'], $groupid, $init_arr); } echo "success";exit;
保存完毕,在浏览器中以以下方式访问该文件:http://bbs.domain.com/activation.php?start=1&end=1000
在ucenter用户表数据量较大的情况下,为避免耗尽服务器资源,可通过调整start和end的值,在执行的时候一批一批,首位交替的进行自动激活。
比如ucenter用户表(pre_ucenter_member)中的前5000个用户(按照uid自小到大排序)的记录与discuz用户表(pre_common_member)
中前5000个用户(按照uid自小到大排序)的记录不同步,就可以依次访问下面的地址,每次同步验证999条记录,直至同步结束:
http://bbs.domain.com/activation.php?start=1&end=1000
http://bbs.domain.com/activation.php?start=1000&end=2000
http://bbs.domain.com/activation.php?start=2000&end=3000
http://bbs.domain.com/activation.php?start=3000&end=4000
http://bbs.domain.com/activation.php?start=4000&end=5000