新浪、腾讯和人人网三家OAuth和API问题相关

最近工作中需要用到网站帐号绑定、OAuth授权相关的功能,所以尽管本意是不想接触OAuth这个明显是“程序员折磨程序员”类型的技术,但也只能硬着头皮去解决问题。今天决定把之中遇到的麻烦和解决过程都记录下来,以免再有人走弯路。

在此之前,推荐大家阅读arthurchenjs的文章从实现iPhone的OAuth封装看国内互联网和开放平台,写得太好了,基本能扫清所有障碍。如果看完之后还有问题没解决、或者你觉得iPhone平台和其他平台实现有区别的话,再继续看我这篇吧。

如果你之前没接触过OAuth,那么最好还是阅读下RFC 5849 – The OAuth 1.0 Protocol,这是OAuth协议的非正式RFC文档。其实所有陌生的技术在了解之初最方便、最省事的方法就是读协议——细化到互联网和IT界,自然是RFC最大。虽然看起来文档协议什么的太长(现在很多人似乎逛BBS逛久了再加上微博兴起,网上文章超过一屏就懒的看)耗费时间,但其实这是最短路径。

然后选择OAuth实现库——没错,我们最好别自己造方形轮子。OAuth协议实现细节比较碎,自己实现费时费力,选择现有的库是最佳方案。但一定要注意所选择代码的协议,例如是否可以不开源、商业应用等。Java平台推荐用SINGPOST,架构灵活,扩展方便,代码量适中。基于同样的原因在iPhone平台上可以选择ShareKit,但我对这个不熟悉,不多说。

新浪微博、腾讯微博和人人网中,前两家用的OAuth 1.0,人人网则使用2.0(因为twitter用1.0而facebook用2.0?)。SIGNPOST的实现基于1.0,所以需要进行一定的改写,或者进行再次封装。

基于同一协议实现的不同网站API使用过程中,会出现有的好用有的却不好用的情况,显然是细节的不同。新浪微博和腾讯微博虽然都声称基于RFC 5849开发,但其明显的区别有:

  1. 用OAuth进行帐号认证时候,新浪微博的验证参数需要通过Header中Authorization域进行传递。腾讯微博则只支持url参数传递。这个地方我当时卡了半天。
  2. 对于桌面客户端,获取verifier时候,新浪微博callback url要传递oob,然后自己从网页中抠那个六位数出来;腾讯微博要传递null,跳转的页面url中会带有verifier参数。
  3. 发送内容的时候,验证参数的位置和OAuth认证时候一样。
  4. 这也是最重要的不同点,在计算Signature Base String时候,新浪微博的参数不需要在组合前进行URL编码,而该死的腾讯必须编码,也就是说,组成SBS时候腾讯微博的参数值实际上被URL编码两次,举例来说就是SBS中content部分的值会有大量的%25字符出现(也就是百分号编码后)。但发送的时候,却只编码一次。我无法理解SBS内容和实际POST出去的内容为什么要不同?但事实就是这样,至于你信不信,试一下就知道了。

在这里顺便对腾讯微博的API文档和不靠谱的论坛技术支持表示无语,API文档里面基本每页都有拼写错误;返回的错误码在文档里找不到说明;甚至于最关键的POST图片时候的包体说明竟然是空白的。

人人网用的OAuth 2.0,大大简化了步骤,自己实现起来速度也很快。不过人人网的文档和API测试机制很扭曲。文档太乱,虽然是Wiki形式但完全看不出组织结构,通常一段内容会在多个页面出现,希望能下功夫整理一下。为什么说测试机制很扭曲,是因为它每个高级接口使用时候都必须经过审核,并且在审核通过前只能用测试帐号进行测试。这个测试帐号的好友数还不能多于5个。但总体来说人人网的API开放会让人觉得不错,是因为出现错误时候返回的信息,准确而且详细。