做者:蔣宇捷(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,二者很類似,包含接口、參數的定義,請求方式等等,假設熟悉Twitter的API,基本可以相同的適用到新浪微博開放平臺上,同一時候此文檔技術部分的信息也可以相同適用於Twitter。api
新浪微博開放平臺的站點爲http://open.t.sina.com.cn/,眼下僅僅部分頁面對匿名用戶開放。新浪微博開放平臺的官方微博爲http://t.sina.com.cn/openapi,可以在此申請API試用權限。跨域
註冊瀏覽器
在開放平臺登陸後可以看到的界面例如如下所看到的:安全
可以選擇建立一個應用,需要設置應用名稱、應用地址等。
建立後可以在「個人應用」菜單裏看到該應用和使用用戶數,系統會爲此應用分配一個APP KEY和APP SECRET,這兩個字串很重要,將會在之後認證或者信息交互時用到。
某應用的具體信息頁面
應用分爲多個受權級別,分別爲普通受權、中級受權、高級受權、合做夥伴受權,可以在http://open.t.sina.com.cn/wiki/index.php/Rate-limiting這裏看到具體的權限信息。使用合做夥伴受權是沒有請求限制的,而普通受權可能一不當心就會Server Limit了。
認證
開放平臺有兩種認證方式,一種是Basic Auth,一種是OAuth。
1、Basic Auth(HTTP Auth)
Basic Auth簡單點說明就是每次請求API時都提供用戶的username和password。好比:
「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校驗的過程。
2、OAuth
OAuth爲用戶資源的受權提供了一個安全、開放的標準,將會是之後開發平臺廣泛遵照的,眼下Twitter、Sina微博、豆瓣、Google等都提供對它的支持。它分爲幾個交互過程:
1)應用用APP KEY和APP 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我將採用PHP和Perl兩種方式,OAuth我將採用PHP和Javascript兩種方式,另外結合命令行來給予全面的說明。
1、Basic Auth之用戶認證
用戶認證的接口是Account/verify credentials,json數據訪問的方式爲「curl -u uid:password http://api.t.sina.com.cn/account/verify_credentials.json?source=appkey」。uid可以是用戶在新浪的username,也可以是用戶編號。
經過命令行運行的結果例如如下所看到的:
命令行請求用戶驗證接口
如下爲PHP用curl方式請求此接口的代碼演示樣例:
$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的方式來實現,可以試試Perl的LWP::Curl和WWW::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>
2、Basic Auth之好友消息獲取
好友消息獲取是一個最常用的功能,能夠取得所關注用戶的最新消息列表。API主要參數包含since_id、max_id、count、page。常用到的是count和since_id。count表示取的消息數量,而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};
}
}
3、Basic Auth之用戶未讀消息獲取
用戶未讀消息獲取的接口是Statuses/unread,json數據訪問方式爲「curl -u uid:password http://api.t.sina.com.cn/statuses/unread.json?source=appkey」。接口將返回用戶未讀消息數,包含@個人,新評論,新私信,新粉絲數。
返回的結果例如如下所看到的:
{"followers":5,"dm":0,"mentions":1,"comments":2}
4、OAuth方式
用PHP開發OAuth方式的新浪微博應用事實上比較簡單,因爲開放平臺提供了SDK供開發者使用,地址見http://code.google.com/p/libweibo/,但是在演示樣例裏index.php裏用$_SERVER[‘SCRIPT_URI’]有可能出現故障,需要用HTTP_HOST和REQUEST_URI構造完整路徑。
這裏我主要想介紹的是用本地應用方式,基於HTML和Javascript的方式實現新浪微博的應用,以實現一個傲遊瀏覽器的插件爲例。
首先要解決幾個問題。
第一,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_callback的json方式,正好幫助咱們解決問題。
應用的結構例如如下圖所看到的:
本地應用的系統結構
配置頁面用於帳戶受權或者取消受權。點擊帳戶受權跳轉到登陸頁面。登陸頁面首先要從request_token API得到未經受權的token,而後在用戶輸入username和password後將參數都提交到authorize API得到verifier,而後跳轉到回調頁面,回調頁面依據verifier和token去access_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的推送,眼下比較好的解決方式有基於Java的Comet,另外Nginx也有一個模塊NGINX_HTTP_Push_Module可以用做server端的推送,配置和使用都比較方便,但是缺點是此模塊並不無缺,僅僅能實現一次推送,推送完成後長連接就會關閉。此外一個簡單的推送辦法是利用HTTP協議的multipart/x-mixed-replace頭,可以實現簡單的server端推送(眼下僅支持firefox和webkit瀏覽器)。用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一覽