标签 QQ互联 下的文章

升级Discuz! X3.1后QQ互联提示connect_error_code_0的问题排查之二

上一篇connect_error_code_0的排查说明

今天在朋友站上做测试,又发现connect_error_code_0的错误。

代码加日志,发现是curl报错了。

错误号:77
错误信息:Problem with reading the SSL CA cert (path? access rights?)

发现不是上次排查遇到的问题,搜索了一番,重装了证书,问题解决。

1. sudo yum install ca-certificates (无论有没有,安装确认一下)
2. 重启php-fpm,这步比较重要,更改底层的东西时一定要重启一下
3. curl时设置:curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0)

不知道是不是跟最近的ssl漏洞有关,原因不知。

参考文章:
解决PHP curl https时error 77(Problem with reading the SSL CA cert (path? access rights?))

QQ互联点击登录提示999报错的问题分析与解决

原因分析

今天收到好几个站点反馈QQ互联登录提示999错误的case,看了下程序,已经是请求互联开放平台的接口了,所以不是云平台的问题导致。

找到其中一个站点,检查站点后台诊断工具情况,发现互联接口请求失败,感觉像是域名解析IP换了,把设置的IP去掉后,请求成功。

ping了下openapi.qzone.qq.com,发现变成了112.90.83.87,确认是域名解析IP变更导致的。

解决方法

  1. 登录站长后台,点击工具-》云平台诊断工具。
  2. 点击QQ互联域名解析后面的设置IP,在弹出来的框里,将QQ互联接口IP里的IP删掉,然后提交。

最新可用的解析IP

如果你的网站通过DNS解析域名有问题,可以设置下面其中一个IP。

深圳电信 183.60.15.158
深圳联通 112.90.83.87

升级Discuz! X3.1后QQ互联提示connect_error_code_0的问题排查

问题表现

升级后,点击QQ互联登录按钮,提示下面的错误信息。

抱歉,当前存在网络问题或服务器繁忙,详细错误:connect_error_code_0,错误代码:,请您稍候再试。

原因分析

Discuz! X3.1的QQ互联集成了OAuth1.0和OAuth2.0的接口,升级脚本判断如果服务器支持ssl,就会使用OAuth2.0接口。
出现此问题的站点属于切换到了OAuth2.0接口后导致的。

source\plugin\manyou\Service\Client\OAuth.php

	public function dfsockopen($requestURL, $queryString = array(), $files = false) {
		return dfsockopen($requestURL, 0, $queryString, '', false, $this->_apiIp, 15, TRUE, !$files ? 'URLENCODE' : 'FORMDATA', true, 0, $files);
	}

注意这里请求url的使用,使用了$this->_apiIp参数,看下这个参数是在哪里定义的。

source\plugin\manyou\Service\Client\ConnectOAuth.php

	public function __construct($connectAppId = '', $connectAppKey = '', $apiIp = '') {

		if(!$connectAppId || !$connectAppKey) {
			global $_G;
			$connectAppId = $_G['setting']['connectappid'];
			$connectAppKey = $_G['setting']['connectappkey'];
		}
		$this->setAppkey($connectAppId, $connectAppKey);
		if(!$this->_appKey || !$this->_appSecret) {
			throw new Exception('connectAppId/connectAppKey Invalid', __LINE__);
		}

		if(!$apiIp) {
			global $_G;
			$apiIp = $_G['setting']['connect_api_ip'] ? $_G['setting']['connect_api_ip'] : '';
		}

		if($apiIp) {
			$this->setApiIp($apiIp);
		}
	}

这里可以看到使用的是后台设置的互联接口IP。

Discuz! 后台诊断工具里的互联接口IP是设置的OAuth1.0接口的域名,即http://openapi.qzone.qq.com。
而OAuth2.0接口的域名变更为了https://graph.qq.com,但是接口里使用的IP仍为OAuth1.0的,所以就导致无法请求,继而导致上述报错。

解决方法

上诊断工具里,去掉设置的互联接口IP即可。

2013年12月17日更新:
看到Discuz! 官网很多人反馈出现网络繁忙的问题,记日志看了下是请求用户openId这步报错了,应该是空间的接口有问题,静待官方解决。

2013年12月18日更新:
已经修复。

Discuz! X1.5版本的缓存丢失问题排查

下午有同事反映之前升级的两个站点开通了QQ互联后出现缓存丢失问题,有一个站点排查发现是由于QQ昵称的特殊字符导致,整理排查过程。

问题描述:

使用QQ登录注册后(QQ昵称带有特殊字符,假设为),论坛缓存出现丢失情况,手动更新后恢复正常,丢失情况类似下图:
[caption id="attachment_971" align="alignnone" width="300"]Discuz! 缓存丢失后的页面 Discuz! 缓存丢失后的页面[/caption]

排查分析:

首先看前台显示,发现注册的“精€€ぷ灵€€”用户名显示成了“精”,进入数据库里的pre_common_member表中确定当前注册的用户名是什么,如图:
[caption id="attachment_972" align="alignnone" width="300"]用户表记录 用户表记录[/caption]

从图可以看出来,注册的“精€€ぷ灵€€”用户名到数据库里变成了“精”,推测是由于Mysql把特殊字符后面的所有东西全部干掉导致。

注册用户时会更新缓存表里的userstats记录,进入pre_common_syscache表里找到对应记录,如图:
[caption id="attachment_973" align="alignnone" width="300"]缓存表记录 缓存表记录[/caption]

从记录可以看出来,这里的序列化结果断掉了,同样的也是从特殊字符开始后面的所有东西都没有了。

至于为什么手动更新缓存就会好,是由于手动更新缓存的时候,最后注册会员的名字是从用户表中查询出来然后再序列化写入缓存表,用户表中的用户名是没有特殊字符的,所以写入缓存表的数据结构是完整的,所以缓存没有问题,有兴趣的童鞋可以参考source\function\cache\cache_userstats.php文件代码。

原因猜测:

个人猜测是由于Mysql不支持特殊字符,插入的带有特殊字符数据,Mysql会将特殊字符及后面的数据全部扔掉。
由于用户名中带有特殊字符,所以缓存表里的记录的序列化值中也会含有特殊字符,同样的抛弃特殊字符及后面的数据,就会导致序列化结构不完整,进而导致前台显示的时候由于反序列化失败导致缓存不完整。

解决方法:

修复普通注册:找到source\module\member\member_register.php文件,搜索下面的代码:

$totalmembers = DB::result_first("SELECT COUNT(*) FROM ".DB::table('common_member'));
$userstats = array('totalmembers' => $totalmembers, 'newsetuser' => $username);

save_syscache('userstats', $userstats);

改为:

require_once libfile('cache/userstats', 'function');
build_cache_userstats();

修复QQ互联注册(仅针对Discuz! X1.5的QQ互联插件):找到source\module\connect\connect_register.php文件,搜索代码:

$totalmembers = DB::result_first("SELECT COUNT(*) FROM ".DB::table('common_member'));
$userstats = array('totalmembers' => $totalmembers, 'newsetuser' => $username);

save_syscache('userstats', $userstats);

改为:

require_once libfile('cache/userstats', 'function');
build_cache_userstats();

搜索代码:

$_G['setting']['lastmember'] = $username;
save_syscache('setting', $_G['setting']);

删除这段代码。

以上的方法可以解决缓存丢失的问题,但是根本的解决方法应该是在用户注册时过滤特殊字符。

版块开启审核的情况下QQ互联无法自动同步的问题分析

下午排查发现一个站点开启了审核的情况下QQ互联无法自动同步的问题,特整理排查过程。

问题描述:

站点端开启了审核功能,所有发帖都先进入待审核状态,审核通过后才可以正常访问,发帖无法自动同步到空间和微博。

代码分析:

找到source/plugin/qqconnect/connect.class.php文件,可以搜索到如下触发自动同步的代码:

if((!getstatus($_G['forum_thread']['status'], 7) || !getstatus($_G['forum_thread']['status'], 8))
         && $_G['forum_thread']['displayorder'] >= 0 && $_G['member']['conisbind']
         && $_G['uid'] == $_G['forum_thread']['authorid']) {
    $_G['connect']['feed_log'] = DB::fetch_first("SELECT * FROM ".DB::table('connect_feedlog')." WHERE tid='$_G[tid]'");
    if($_G['connect']['feed_log']) {
        $_G['connect']['feed_interval'] = 300;
        $_G['connect']['feed_publish_max'] = 1000;
        if(getstatus($_G['connect']['feed_log']['status'], 1) || (getstatus($_G['connect']['feed_log']['status'], 2)
            && TIMESTAMP - $_G['connect']['feed_log']['lastpublished'] > $_G['connect']['feed_interval']
            && $_G['connect']['feed_log']['publishtimes'] < $_G['connect']['feed_publish_max'])) {
            $_G['connect']['feed_js'] = $feedlogstatus = true;
        }

        if(getstatus($_G['connect']['feed_log']['status'], 3) || (getstatus($_G['connect']['feed_log']['status'], 4)
            && TIMESTAMP - $_G['connect']['feed_log']['lastpublished'] > $_G['connect']['feed_interval']
            && $_G['connect']['feed_log']['publishtimes'] < $_G['connect']['feed_publish_max'])) {
            $_G['connect']['t_js'] = $tlogstatus = true;
        }

        if($feedlogstatus || $tlogstatus) {
            $status = $feedlogstatus ? setstatus(2, 1, $status) : $status;
            $status = $tlogstatus ? setstatus(4, 1, $status) : $status;
            DB::query("UPDATE ".DB::table('connect_feedlog')." SET status='$status', lastpublished='$_G[timestamp]', publishtimes=publishtimes+1 WHERE tid='$_G[tid]'");
        }
    }
}

其中的$_G['connect']['feed_js']和$_G['connect']['t_js']两个变量为控制是否触发自动同步到空间和微博的变量。
注意开头的if判断里的下面这句:

&& $_G['member']['conisbind'] && $_G['uid'] == $_G['forum_thread']['authorid']

这里要求是发帖人自己访问的时候才会触发自动同步的代码。

结论:

前面提到站点开启了审核功能,所有发帖都会先进入待审核状态,由管理人员审核通过后其他人才可以正常访问到。
当帖子被审核通过后,如果发帖人没有重新访问过自己的帖子,那么同样是不会自动同步到空间和微博的。

另外,自动同步的帖子是有时间限制的,如果发帖时间距当前时间超过12个小时,即使发帖人重新访问自己的帖子,这个时候也不会再触发自动同步了。