新浪微博開放平臺深度歷險

做者:蔣宇捷(hfahe)php

版權聲明:原創做品,歡迎轉載,轉載時請務必以超連接形式標明文章原始出處 、做者信息和本聲明。html

 

10月21日補充web

解決Ajax跨域的方法ajax

可經過新浪提供的JS SDK解決,詳情參考http://open.t.sina.com.cn/wiki/index.php/JS-SDK,需要在server嵌入xd.html文件。算法

 

簡單介紹json

         新浪微博開放平臺的體系參考了Twitter,二者很類似,包含接口、參數的定義,請求方式等等,假設熟悉TwitterAPI,基本可以相同的適用到新浪微博開放平臺上,同一時候此文檔技術部分的信息也可以相同適用於Twitterapi

         新浪微博開放平臺的站點爲http://open.t.sina.com.cn/,眼下僅僅部分頁面對匿名用戶開放。新浪微博開放平臺的官方微博爲http://t.sina.com.cn/openapi,可以在此申請API試用權限。跨域

註冊瀏覽器

         在開放平臺登陸後可以看到的界面例如如下所看到的:安全

 

         可以選擇建立一個應用,需要設置應用名稱、應用地址等。

         建立後可以在「個人應用」菜單裏看到該應用和使用用戶數,系統會爲此應用分配一個APP KEYAPP SECRET,這兩個字串很重要,將會在之後認證或者信息交互時用到。

 

某應用的具體信息頁面

         應用分爲多個受權級別,分別爲普通受權、中級受權、高級受權、合做夥伴受權,可以在http://open.t.sina.com.cn/wiki/index.php/Rate-limiting這裏看到具體的權限信息。使用合做夥伴受權是沒有請求限制的,而普通受權可能一不當心就會Server Limit了。

認證

         開放平臺有兩種認證方式,一種是Basic Auth,一種是OAuth

         1Basic AuthHTTP Auth

         Basic Auth簡單點說明就是每次請求API時都提供用戶的usernamepassword。好比:

curl -u user:password -d "source=10001&status=api test" http://api.t.sina.com.cn/update.xml

。這樣的方式長處和缺點都很是明顯。

         長處:

u  使用很easy,

u  開發和調試工做簡單,

u  沒有複雜的頁面跳轉邏輯和交互過程;

u  更利於發起方控制;

         缺點:

u  安全性低,每次都需要傳遞username和password,username和password很是大程度上存在被監聽盜取的可能;

u  同一時候應用本地還需要保存username和password,在應用自己的安全性來講,也存在很是大問題;

u  開放平臺服務商出於自身安全性的考慮(第三方可以獲得該服務商用戶的帳號password,對於服務商來講是一種安全隱患),將來也會限制此認證方式(Twitter就計劃在6月份中止Basic Auth的支持)

u  用戶假設更改了username和password,還需要又一次進行password校驗的過程。

         2OAuth

         OAuth爲用戶資源的受權提供了一個安全、開放的標準,將會是之後開發平臺廣泛遵照的,眼下TwitterSina微博、豆瓣、Google等都提供對它的支持。它分爲幾個交互過程:

         1)應用用APP KEYAPP SECRET換取OAuth_token

         2)應用將用戶引導到服務商的頁面對該OAuth_token進行受權(可能需要輸入username和password);

         3)服務商的頁面跳轉回應用,應用再依據參數去服務商得到Access Token

         4)使用這個Access Token就可以訪問API了。

         上述步驟例如如下圖所看到的:

 

    

OAuth認證過程

         OAuth的長處:

u  安全性高,用戶的帳戶和password僅僅需要提供一次,而且是在服務商的頁面上提供,防止了Basic Auth重複傳輸password帶來的安全隱患;

u  Access Token訪問權限僅限於應用,被竊取不會影響用戶在該服務商的其它服務;

u  Access Token即便被監聽丟失了隨時可以撤銷,不像password丟失可能就被別人篡改了;

u  用戶改動了password也不會影響該應用的正常使用。

         詳細OAuth的分析詳見這篇文章:http://blog.csdn.net/hereweare2009/archive/2009/03/08/3968582.aspx,標準文檔見http://docs.google.com/View?id=dcmnpkqd_2wxwfwrdg

         新浪微博開放平臺提供了多種類型的認證頁面,好比如下的圖:

 

標準的受權頁面

 

彈出窗體類型的受權頁面

開發

         開放平臺的API接口基本都是以RESTFUl的方式給出,有統一的參數和響應格式。

         實際開發的樣例,Basic Auth我將採用PHPPerl兩種方式,OAuth我將採用PHPJavascript兩種方式,另外結合命令行來給予全面的說明。

         1Basic Auth之用戶認證

         用戶認證的接口是Account/verify credentialsjson數據訪問的方式爲「curl -u uid:password http://api.t.sina.com.cn/account/verify_credentials.json?source=appkey」。uid可以是用戶在新浪的username,也可以是用戶編號。

         經過命令行運行的結果例如如下所看到的:

        

命令行請求用戶驗證接口

         如下爲PHPcurl方式請求此接口的代碼演示樣例:

         $username = $_POST['username'];         

         $password = $_POST['password'];

         // param validate

         // …

         $curl = curl_init();

        

         curl_setopt($curl, CURLOPT_URL, "http://api.t.sina.com.cn/account/verify_credentials.json?source=xxxxxxx");

         curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

         curl_setopt($curl, CURLOPT_USERPWD, "$username:$password");

        

         $data = curl_exec($curl);

                  

         curl_close($curl);

         假設用Perl的方式來實現,可以試試PerlLWP::CurlWWW::Curl模塊,或者簡單用運行系統命令方式實現,代碼例如如下:

         my $json = `curl -u $username:$password -d count=3 -d since_id=$since_id http://api.t.sina.com.cn/account/verify_credentials.json?source=xxxxxxx`;

         假設認證成功,返回的是用戶我的信息,假設認證失敗,將返回錯誤信息,好比:

         <?xml version="1.0" encoding="UTF-8"?><hash><request>/account/verify_credentials.xml</request><error_code>400</error_code><error>Error: source paramter(appkey) is missing</error></hash>

         2Basic Auth之好友消息獲取

         好友消息獲取是一個最常用的功能,能夠取得所關注用戶的最新消息列表。API主要參數包含since_idmax_idcountpage。常用到的是countsince_idcount表示取的消息數量,而since_id表示從哪條消息開始取,假設要作增量更新功能,就行記錄每一次最新一條消息的id,而後下一次將這一條消息的id做爲since_id去請求接口。

         經過命令行請求此接口例如如下圖所看到的:

 

命令行請求好友消息接口

         從返回的json數據裏取得一條消息的內容、發表時間、用戶暱稱、用戶頭像等信息,Perl可以採用例如如下的代碼:

         my $statuses = JSON::from_json($json);

         if(@$statuses[0]) { # must have new messages

                  for my $status ( @$statuses ) {

                            my $name = $status->{user}{screen_name};

                            my $text = $status->{text};

                            my $create_at = $status->{created_at};

                            my $id = $status->{id};

                            my $img = $status->{user}->{profile_image_url};

                  }

         }

         3Basic Auth之用戶未讀消息獲取

         用戶未讀消息獲取的接口是Statuses/unreadjson數據訪問方式爲「curl -u uid:password http://api.t.sina.com.cn/statuses/unread.json?source=appkey」。接口將返回用戶未讀消息數,包含@個人,新評論,新私信,新粉絲數。

         返回的結果例如如下所看到的:

         {"followers":5,"dm":0,"mentions":1,"comments":2}

         4OAuth方式

         PHP開發OAuth方式的新浪微博應用事實上比較簡單,因爲開放平臺提供了SDK供開發者使用,地址見http://code.google.com/p/libweibo/,但是在演示樣例裏index.php裏用$_SERVER[‘SCRIPT_URI’]有可能出現故障,需要用HTTP_HOSTREQUEST_URI構造完整路徑。

         這裏我主要想介紹的是用本地應用方式,基於HTMLJavascript的方式實現新浪微博的應用,以實現一個傲遊瀏覽器的插件爲例。

         首先要解決幾個問題。

         第一,Ajax跨域問題:咱們從本地經過Javascript請求新浪微博API時,都是跨域的。解決方案很是多,1、使用PHP作一個本域的訪問代理,固然用這樣的方式就算不上純本地應用了;2、使用Ajax跨域方法,好比動態的Script標籤;3、假設是傲遊的插件,這算不上是一個問題,因爲瀏覽器的插件可以跨域訪問遠程地址。

         第二,加密算法問題:OAuth的請求需要進行簽名,需要算法的支持。新浪微博開放平臺的文檔建議採用HMAC-SHA1方式。js有一個sha1的類庫,裏面實現了常用的SHA1加密算法。使用裏面的b64_hmac_sha1方法就可以獲得符合格式的簽名。

         第三,頁面跳轉問題:在OAuth流程裏,有一步是重新浪用戶受權頁面跳轉到應用的callback頁面,這一個過程在本地應用來講,是有問題的。以傲遊瀏覽器爲例,打開頁面都是以本地文件的方式(file:///),此頁面不存在一個網絡上的地址,因此,將file:///開頭的地址做爲callback地址給新浪用戶受權頁面時,經過後臺跳轉的它沒法解析此頁面的地址,也沒法跳轉到對應的本地頁面(就是說此頁面必須有在一個肯定的域名下)。這個問題是很是難解決的,而從瀏覽器端進行修改代價太大,幸虧新浪微博受權API爲不方便訪問Web頁面的應用提供了oauth_callbackjson方式,正好幫助咱們解決問題。

         應用的結構例如如下圖所看到的:

本地應用的系統結構

         配置頁面用於帳戶受權或者取消受權。點擊帳戶受權跳轉到登陸頁面。登陸頁面首先要從request_token API得到未經受權的token,而後在用戶輸入username和password後將參數都提交到authorize API得到verifier,而後跳轉到回調頁面,回調頁面依據verifiertokenaccess_token API得到通過受權的token,認證過程完畢。token保存在本地(cookies、本地文件、瀏覽器帳戶配置等方式),之後每次獲取消息或者發表消息都需要使用此token。消息顯示頁面可以經過Ajax增量更新或者定時刷新頁面的方式來更新用戶信息。如下是獲取request_token的核心代碼。

         function get_request_token() {

         var param_arr = ["oauth_consumer_key=" + oauth_consumer_key,

                    "oauth_nonce=" + oauth_nonce,

                    "oauth_signature_method=" + oauth_signature_method,

                    "oauth_timestamp=" + oauth_timestamp,

                    "oauth_version=" + oauth_version];

         base_string = oauth_method + "&" + encodeURIComponent(request_token_api) + "&" + encodeURIComponent(param_arr.join("&"));

         oauth_signature = b64_hmac_sha1(app_secret + "&", base_string) + "=";

        

         args = "oauth_consumer_key=" + encodeURIComponent(oauth_consumer_key)

                   + "&oauth_nonce=" + encodeURIComponent(oauth_nonce)

                   + "&oauth_timestamp=" + encodeURIComponent(oauth_timestamp)

                   + "&oauth_signature_method=" + encodeURIComponent(oauth_signature_method)

                   + "&oauth_signature=" + encodeURIComponent(oauth_signature)

                   + "&oauth_version=" + encodeURIComponent(oauth_version);

 

         Lite.IO.ajaxGet(request_token_proxy, args, set_oauth_token_callback);

}

         傲遊瀏覽器插件的一個簡單效果圖例如如下圖所看到的:

 

新浪微博開放平臺應用-傲遊瀏覽器插件示意圖

推送與抓取

         上述的解決方式都是基於應用自身抓取的方式,需要定時進行。而實現新浪微博到應用的推送功能據新浪內部消息,此接口正在開發中。

         而實現應用從server端到client的推送,眼下比較好的解決方式有基於JavaComet,另外Nginx也有一個模塊NGINX_HTTP_Push_Module可以用做server端的推送,配置和使用都比較方便,但是缺點是此模塊並不無缺,僅僅能實現一次推送,推送完成後長連接就會關閉。此外一個簡單的推送辦法是利用HTTP協議的multipart/x-mixed-replace頭,可以實現簡單的server端推送(眼下僅支持firefoxwebkit瀏覽器)。用PHP實現的話可以調用一個現成的類庫- http://www.google.cn/codesearch/p?hl=zh-CN#CAa88S9-H3Q/saf/lib/CGI/Cookie.php&q=serverpush%20php&d=3,而後用例如如下的代碼就可以看到server端推送的效果了。

         <?php

        

         $spush = new ServerPush ('replace');

        

         // display the message "Hello, how are you today?" one word at a time

         // with a two second delay between words.

         $spush->rotate (array (

              'Hello,',

              'how',

              'are',

              'you',

              'today?',

         ), 2);

         

         ?>

其它

         我很是好奇的研究了Chrome的插件Sina Twitter,驚奇的發現它並無使用新浪的不論什麼API,全然是基於頁面抓取實現的,這也是從另一個實現新浪微博插件的思路。

         至於要實現Twitter的應用,可以使用一個叫class.twitter.php的類庫,已經封裝了很是多功能(但是另外一些不無缺的地方,我我的也對它進行了一些改進)。

附:新浪微博開放API一覽

獲取下行數據集(timeline)接口

微博訪問接口

用戶接口

  • users/show 依據用戶ID獲取用戶資料(受權用戶)
  • statuses/friends 獲取當前用戶關注對象列表及最新一條微博信息
  • statuses/followers 獲取當前用戶粉絲列表及最新一條微博信息

私信接口

關注接口

Social Graph接口

帳號接口

收藏接口

登陸/OAuth接口

重要字段說明

取自"http://open.t.sina.com.cn/wiki/index.php/Rest_API"

相關文章
相關標籤/搜索