使用 PECL 的 OAuth 库访问 QQ 微博 API

大势所趋,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 编译依赖的一个包,主要用来支持正则表达式:

<br />
sudo apt-get install php5-dev php-pear libpcre3-dev<br />

使用 pecl 安装 OAuth:

<br />
sudo pecl install oauth<br />

在 /etc/php5/apache2/conf.d/ 下建立文件 oauth.ini,加内容:

<br />
extension=oauth.so<br />

重启 web 服务器:

<br />
sudo apache2ctl restart<br />

好了,OAuth 扩展加载完成。

在演示中,只做两件事情:1、利用 OAuth 完成身份验证。2、取得身份验证后获取大厅消息。

下面是代码,不罗嗦了,注释里说明。

define.php

<br />
&lt;?php<br />
define('OAUTH_KEY', '应用信息里的 App Key');<br />
define('OAUTH_SECRET', '应用信息里的 App Secret');</p>
<p>define('REQUEST_TOKEN', 'https://open.t.qq.com/cgi-bin/request_token');<br />
define('AUTHORIZE', 'https://open.t.qq.com/cgi-bin/authorize');<br />
define('ACCESS_TOKEN', 'https://open.t.qq.com/cgi-bin/access_token');</p>
<p>define('CALLBACK', 'http://xxiyy.com/qqt/callback.php');</p>
<p>session_id('XY');<br />
session_start();<br />

index.php

<br />
&lt;?php<br />
include('define.php');<br />
try {<br />
    $oauth = new OAuth(OAUTH_KEY, OAUTH_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);<br />
    $oauth-&gt;enableDebug();<br />
    // 很重要!!!在 OAuth 标准里是没有规定 nonce 的长度的,但是 QQ 对 nonce 的长度做了要求——32 字节长。如果不设置一下,会返回 400 错误。我为此纠结了一天。<br />
    $oauth-&gt;setNonce(md5(rand()));<br />
    // CALLBACK 一定要设置,OAuth 扩展的文档上是没设置的,但是 QQ 这里不设会报错<br />
    $requestTokenInfo = $oauth-&gt;getRequestToken(REQUEST_TOKEN, CALLBACK);<br />
    $_SESSION['oauth_token_secret'] = $requestTokenInfo['oauth_token_secret'];<br />
    // header(&quot;Location: ……&quot;) 亦可<br />
    echo &quot;&lt;p&gt;&lt;a href='&quot; . AUTHORIZE . &quot;?oauth_token=&quot; . $requestTokenInfo['oauth_token'] . &quot;'&gt;authorize&lt;/a&gt;&lt;/p&gt;&quot;;<br />
} catch (OAuthException $e) {<br />
    var_dump($e);<br />
}<br />

callback.php

<br />
&lt;?php<br />
include('define.php');<br />
try {<br />
    $oauth = new OAuth(OAUTH_KEY, OAUTH_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);<br />
    $oauth-&gt;enableDebug();<br />
    // 很重要!!!如果不设置一下,会返回 401 错误。<br />
    $oauth-&gt;setNonce(md5(rand()));<br />
    $oauth-&gt;setToken($_GET['oauth_token'], $_SESSION['oauth_token_secret']);<br />
    $accessTokenInfo = $oauth-&gt;getAccessToken(ACCESS_TOKEN, null, $_GET['oauth_verifier']);<br />
    $_SESSION['access_token'] = $accessTokenInfo['oauth_token'];<br />
    $_SESSION['access_secret'] = $accessTokenInfo['oauth_token_secret'];<br />
    header('Location: room.php');<br />
} catch (OAuthException $e) {<br />
    var_dump($e);<br />
}<br />

room.php

<br />
&lt;?php<br />
include('define.php');<br />
try {<br />
    $url = &quot;http://open.t.qq.com/api/statuses/public_timeline?format=json&amp;pos=0&amp;reqnum=10&quot;;</p>
<p>    $oauth = new OAuth(OAUTH_KEY, OAUTH_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);<br />
    $oauth-&gt;enableDebug();<br />
    $oauth-&gt;setToken($_SESSION['access_token'], $_SESSION['access_secret']);<br />
    $oauth-&gt;fetch($url);<br />
    $json = json_decode($oauth-&gt;getLastResponse());<br />
    var_dump($json);<br />
} catch (OAuthException $e) {<br />
    var_dump($e);<br />
}<br />

完整代码:下载

PS:多说两句。今天微博上看到关于 QQ 开放的 API 有一些讨论,似乎认可度不高。不过,虽然腾讯这次开放的微博 API 还有很多不足,尤其是开发者支持和文档方面。但说句公道话,还远未达到“令人畏惧”的程度(你们想看看更“令人畏惧”的吗?)。按照腾讯一贯的风格:持续迭代、快速改进,应该很快会有新的支持。

尝试一下这个:

貌似有问题,带不上地址呢?我又搞错什么了?

6 thoughts on “使用 PECL 的 OAuth 库访问 QQ 微博 API”

  1. 楼主这是基于OAuth 1.0*的扩展
    请问下 该扩展 是否支持 OAuth2.0 协议呢
    或者目前有木有这样的扩展可以用,谢谢

Leave a Reply

Your email address will not be published. Required fields are marked *