大势所趋,QQ 也在自家门上开了个小洞让诸位看客过过瘾。不过 API 文档不给力,疏漏多、讲得粗,没有 SDK,没有 Step by step,关键细节交代不清……幸而,摸索两日,总算是探得一个靠谱的办法——PECL 的 OAuth 库访问。
特别记录于此,供众玩家观赏。
在使用 PECL 的 OAuth 库之前,尝试过包括 oauth-php 在内的一些第三方库。有些跟 QQ 的 API 不兼容(不要信什么大家都是严格按照 RFC 实现之类的浮云);有些自己正常运行都有问题;还有些我觉得作为一个 API 调用界面,本身设计的用法就太过复杂,封装层次太高……本想用熟悉的 Zend_OAuth,但是想到 Zend 的那个大块头……幸有 PECL!
不过 PECL 也不是人人都能用的,毕竟这个玩意是个要额外安装的家伙。大家酌情选择吧……
先讲讲我的运行环境。我使用的是 linode 的 VPS 主机,最便宜的那种。装的是 Ubuntu 10.4,Apache2、PHP5 这些都是 apt 装的。个人觉得,我投入的那点精力优化出来的编译参数不一定会比 ubuntu 的团队做得更好。
所以 OAuth 扩展的安装是非常的简单,首先安装 php 的编译依赖和 pear 包。libpcre3 是 OAuth 编译依赖的一个包,主要用来支持正则表达式:
sudo apt-get install php5-dev php-pear libpcre3-dev
使用 pecl 安装 OAuth:
sudo pecl install oauth
在 /etc/php5/apache2/conf.d/ 下建立文件 oauth.ini,加内容:
extension=oauth.so
重启 web 服务器:
sudo apache2ctl restart
好了,OAuth 扩展加载完成。
在演示中,只做两件事情:1、利用 OAuth 完成身份验证。2、取得身份验证后获取大厅消息。
下面是代码,不罗嗦了,注释里说明。
define.php
<?php define('OAUTH_KEY', '应用信息里的 App Key'); define('OAUTH_SECRET', '应用信息里的 App Secret'); define('REQUEST_TOKEN', 'https://open.t.qq.com/cgi-bin/request_token'); define('AUTHORIZE', 'https://open.t.qq.com/cgi-bin/authorize'); define('ACCESS_TOKEN', 'https://open.t.qq.com/cgi-bin/access_token'); define('CALLBACK', 'http://xxiyy.com/qqt/callback.php'); session_id('XY'); session_start();
index.php
<?php include('define.php'); try { $oauth = new OAuth(OAUTH_KEY, OAUTH_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI); $oauth->enableDebug(); // 很重要!!!在 OAuth 标准里是没有规定 nonce 的长度的,但是 QQ 对 nonce 的长度做了要求——32 字节长。如果不设置一下,会返回 400 错误。我为此纠结了一天。 $oauth->setNonce(md5(rand())); // CALLBACK 一定要设置,OAuth 扩展的文档上是没设置的,但是 QQ 这里不设会报错 $requestTokenInfo = $oauth->getRequestToken(REQUEST_TOKEN, CALLBACK); $_SESSION['oauth_token_secret'] = $requestTokenInfo['oauth_token_secret']; // header("Location: ……") 亦可 echo "<p><a href='" . AUTHORIZE . "?oauth_token=" . $requestTokenInfo['oauth_token'] . "'>authorize</a></p>"; } catch (OAuthException $e) { var_dump($e); }
callback.php
<?php include('define.php'); try { $oauth = new OAuth(OAUTH_KEY, OAUTH_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI); $oauth->enableDebug(); // 很重要!!!如果不设置一下,会返回 401 错误。 $oauth->setNonce(md5(rand())); $oauth->setToken($_GET['oauth_token'], $_SESSION['oauth_token_secret']); $accessTokenInfo = $oauth->getAccessToken(ACCESS_TOKEN, null, $_GET['oauth_verifier']); $_SESSION['access_token'] = $accessTokenInfo['oauth_token']; $_SESSION['access_secret'] = $accessTokenInfo['oauth_token_secret']; header('Location: room.php'); } catch (OAuthException $e) { var_dump($e); }
room.php
<?php include('define.php'); try { $url = "http://open.t.qq.com/api/statuses/public_timeline?format=json&pos=0&reqnum=10"; $oauth = new OAuth(OAUTH_KEY, OAUTH_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI); $oauth->enableDebug(); $oauth->setToken($_SESSION['access_token'], $_SESSION['access_secret']); $oauth->fetch($url); $json = json_decode($oauth->getLastResponse()); var_dump($json); } catch (OAuthException $e) { var_dump($e); }
完整代码:下载
PS:多说两句。今天微博上看到关于 QQ 开放的 API 有一些讨论,似乎认可度不高。不过,虽然腾讯这次开放的微博 API 还有很多不足,尤其是开发者支持和文档方面。但说句公道话,还远未达到“令人畏惧”的程度(你们想看看更“令人畏惧”的吗?)。按照腾讯一贯的风格:持续迭代、快速改进,应该很快会有新的支持。
Leave a Reply