Oauth認證-新浪微博開發(上)

Oauth認證-新浪微博開發(上)
2012-03-27 17:42:16
最近幾天一直在學習新浪微博的授權驗證,在論壇上下了個例子,也找到了相關的博客文章。。以爲很簡單能搞懂,但是費了很長時間,還是一頭霧水。。後來想想,其實別人提供的只是一些接口、方法,而我對授權的過程並沒有認真的學習過,所以對於代碼中那些奇怪的方法倍感陌生。。現在把自己的一些心得補充進來。
原文博客:http://www.cnblogs.com/hll2008/archive/2011/01/03/1924952.html
對於界面及數據庫使用就不在囉嗦,只詮釋下授權驗證部分。 
新浪微博授權支持Oauth1.0 和Oauth2.0 ,後者對前者在過程中有所改變,詳細信息可參考:
Oauth1.0 http://open.weibo.com/wiki/Oauth
Oauth2.0 http://open.weibo.com/wiki/index.php?title=Oauth2&redirect=no

授權機制:
大部分REST API的訪問如發表微博,獲取私信都需要用戶身份。目前用戶身份鑑權有OAuth和Basic Auth(僅用於開發者調試接口)兩種方式。

OAuth

OAuth是一種國際通用的授權方式, OAuth的官方技術說明可參看 http://oauth.net/2/ (英文)。
新浪微博開放平臺已推出OAuth2.0,同時提供對Web,桌面和移動應用程序的支持,並較1.0相比整個授權驗證流程更簡單更安全。也是未來最主要的用戶身份驗證和授權方式。

HTTP普通鑑權(Basic Authentication)方式

Basic Authentication是一種通過HTTP頭傳遞用戶身份的授權方式。在非HTTPS方式下使用存在密碼被竊聽風險。採用普通鑑權(Basic Authentication)時app_key(consumer key)通過請求參數直接傳遞,參數名爲 source=consumer key,如
curl -u user:password -d "source=10001&status=api test" http://api.t.sina.com.cn/statuses/update.xml 
Basic Auth編程也可以參看這篇文章 http://www.cnblogs.com/QLeelulu/archive/2009/11/22/1607898.html
當前Basic Authentication僅用於開發者調試API接口。
新浪開發平臺提供一套SDK(下載地址http://open.weibo.com/wiki/SDK),你可以調用其方法實現新浪微博的授權。
不過這種方式不具有通用性,原博客中採用Oauth1.0 方式,同時使用Signpost(開源項目)實現Oauth簽名。
SignPost
Signpost 是一個簡單而且直觀的使用 OAuth 1.0 規範對 HTTP 消息進行簽名的 Java 解決方案。
參考上面內容,我們詳細的學習下如何使用signpost進行Oauth認證的。
瞭解授權過程
以新浪微博爲例,爲了使用新浪微博開放平臺提供的API(應用程序接口),你需要先註冊一個應用,獲得一個專屬的App Key和App Secret。Key跟Secret的使用方式跟其他一些協議中的公鑰私鑰的方案相類似,你可以使用你所熟悉的編程語言將key和secret結合,爲你發出的每個請求添加簽名,以此來向新浪微博開放平臺表明自己身份的合法性。
OAuth請求循環可以分爲如下四步:
oauth_flowchart.jpg
OAuth提供兩種認證方式:query-string和http headers。我們推薦使用http header進行認證。
請求籤名

oauth/request_token

通過訪問該接口獲取未授權的 Request Token訪問以get方式請求,幷包含以下參數:
  • oauth_consumer_key: 創建應用時生成的APP KEY。
  • oauth_signature_method: 簽名方法,建議使用“HMAC-SHA1”。
  • oauth_timestamp:時間戳。生成Base String時的時間戳。
  • oauth_nonce:單次值,一個隨機字符串,防止重複攻擊。該字段只支持ASCII碼的字符。
  • oauth_version : OAuth協議版本。填寫“1.0”。
  • oauth_signature:簽名值,是由根據上面的5個參數生成的 Base String經HMAC-SHA1算法計算得出。
所有的OAuth請求使用同樣的算法來生成(signature base string)簽名字符基串和簽名。base string是把http方法名,請求URL以及請求參數用&字符連起來後做URL Encode編碼。
簽名字符基串:把http方法名,請求URL以及請求參數用&字符連起來後做URL Encode編碼,無論生成何種OAuth1.0請求,生成BASE STRING的規則始終不變。
具體來講,base string由http方法名,之後是&,接着是過url編碼(url-encoded)之後的url和訪問路徑及&。接下來,把所有的請求參數包括POST方法體中的參數,經過排序(按參數名進行文本排序,如果參數名有重複則再安參數值進行重複項目排序),使用=替代=號,並且使用&作爲每個參數之間的分隔符,拼接成一個字符串。這個算法可以簡單表示爲:
httpMethod + "&" + url_encode( base_uri ) + "&" + sorted_query_params.each { | k, v | url_encode ( k ) + "=" + url_encode ( v ) }.join("&")

簽名:由簽名字符基串按一定算法計算出來。(如HMAC-SHA1)
新浪微博要求所有的OAuth請求都使用HMAC-SHA1算法生成簽名。

返回值

oauth_token=8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc&oauth_token_secret=x6qpRnlEmW9JbQn4PQVVeVG8Z

獲取request token

request token是進行用戶認證的第一步。這一步主要有兩個目的:
第一,告訴新浪微博你將要做什麼
第二,告訴新浪微博你在callback裏要做什麼
下面舉個例子,以下是請求用的參數:(注意,這裏是請求用到的參數,並不一定是【請求參數】)
consumer secret - "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" 這個做什麼用 ?
oauth_callback - http://localhost:3005/the_dance/process_callback?service_provider_id=11 授權後的重定向的URL
oauth_consumer_key - GDdmIQH6jhtmLUypg82g 創建應用時生成的APP KEY。
oauth_nonce - QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk 單次值,一個隨機字符串,防止重複攻擊
oauth_signature_method - HMAC-SHA1 簽名方法
oauth_timestamp - 1272323042 時間戳
oauth_version - OAuth協議版本

我的理解:請求時,使用consumer_secret作爲密鑰對請求參數進行加密,而傳輸過程中只傳輸公鑰(consumer_key),所以在接口參數中只有oauth_consumer_key,而沒有包含上文提到的consumer_secret。
比如,文中提到的oauth_callback等參數作爲字符基串,生成oauth_signature:簽名值,再作爲請求參數傳輸。

第一步,用上文提到的算法形成BASE STRING。需要注意的是callback在URL中包含請求參數,由於參數只CALLBACK URL的一部分,所以並不需要將其提出成爲獨立的參數。 URL必須按照單個字符串來考慮。生成的BASE STRING如下:
POST&https://api.t.sina.com.cn/oauth/request_token&oauth_callback=http://loca
由於我們還未獲取到oauth_token和oauth_token_secret,所以我們的BASE STRING裏沒有包含oauth_token和oauth_token_secret。
接下來使用signing key(App Secret後加一個&符)從base string生成oauth_signature:?
8wUi7m5HFQy76nowoCThusfgB+Q=
接下來就可以向http://api.t.sina.com.cn/oauth/request_token 發送請求。生成的http header如下:
OAuth oauth_nonce="QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk", 
oauth_callback="http://localhost:3005
當服務器端接到請求之後,會返回包含oauth_token,oauth_token_secret等內容,另外oauth_callback_confirmed字段如果爲true就表示callback生效。服務器端的響應如下:
oauth_token=8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc&oauth_token_secret=x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA&oauth_callback_confirmed=true  
這時需要將oauth_token和oauth_token_secret記下,我們需要用這個參數來獲取access token。

用戶認證

這一步主要是發送你獲取的oauth_token,並且獲得用戶的授權。一般來說,WEB應用會簡單的重定向到相應的頁面,桌面應用程序會給出URL並要求用戶自行驗證.
新浪微博開放平臺的驗證URL是http://api.t.sina.com.cn/oauth/authorize 。要求必須以oauth作爲參數,一般來說請求格式如下:
如使用XML/JSON返回方式(參看後文),需傳遞以下附加參數:
  • oauth_token 上一步獲(即:oauth/request_token接口調用)取到的oauth token
  • oauth_callback, 需要進行url encode
  • display,定義頁面調用類型,目前我們提供了6種調用類型
    普通web調用:display=page 這個也是默認調用類型
    Android,iPhone調用:display=mobile
  wap訪問頁面自動調用:display=wap 我們會根據信息頭來判斷是wap1.2還是wap2.0
wap1.2頁面調用:display=wap1.2 供wap1.2訪問
wap2.0頁面調用:display=wap2.0 供wap2.0訪問
    popup彈窗調用:display=popup
json 或 xml(通常移動終端使用)
  • userId 新浪通行證賬戶名
  • passwd 密碼

使用說明

  • 當請求參數 oauth_callback=oob 則表明爲桌面應用,會提示用戶做桌面應用操作.
部分移動終端客戶端可能不方便訪問Web/WAP頁面,可以使用以下方法
  • oauth_callback=json, 頁面直接返回參數
{"oauth_token":"c248561721393a78260b8d00ece7d703", "oauth_verifier":"234256"}
  • oauth_callback=xml, 頁面直接返回參數
<oauth_token>c248561721393a78260b8d00ece7d703</oauth_token> <oauth_verifier>234256</oauth_verifier>
如果用戶沒有登錄新浪微博,則會要求用戶登錄。否則將會出現一個頁面,用戶可以在此頁面上一鍵同意或者拒絕對此應用授權。用戶授權後,web應用頁面將會重定向至你指定的oauth_callback,如果是桌面應用,將會顯示PIN碼,用戶需要將PIN碼輸入你的應用中來完成授權過程。
如果使用了callback,那麼oauth_callback應該已經接到返回的信息,其中包含oauth_token和oauth_verifier。樣例如下:
oauth_token=8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc&oauth_verifier=pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY

這一步,我們需要獲取oauth_token ,oauth_verifier。

獲取access token(授權過的Oauth_token)

新浪微博開放平臺access token請求地址爲:http://api.t.sina.com.cn/oauth/access_token
以下是請求參數列表:
 oauth_consumer_key - GDdmIQH6jhtmLUypg82g 創建應用時生成的APP KEY。
oauth_nonce - 9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8 單次值,一個隨機字符串 oauth_signature_method - HMAC-SHA1 簽名方法
oauth_token - 8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc 經過用戶授權的Request Token。
oauth_timestamp - 1272323047 時間戳
oauth_verifier - pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY 可選。在oauth/authorize這一步中,新浪微博給出的認證碼。
oauth_version - 1.0 Oauth版本號
oauth_token_secret - x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA

參數說明:
  • oauth_consumer_key: 創建應用時生成的APP KEY。
  • oauth_token:經過用戶授權的Request Token。
  • oauth_signature_method: 簽名方法,建議使用“HMAC-SHA1”。
  • oauth_timestamp:時間戳。生成Base String時的時間戳。
  • oauth_nonce:單次值,一個隨機字符串,防止重複攻擊。該參數只支持ASCII碼的字符串.
  • oauth_version : OAuth協議版本。填寫“1.0”。
  • oauth_verifier: 可選。在oauth/authorize這一步中,新浪微博給出的認證碼。
  • oauth_signature:簽名值,是由根據上面的幾個參數生成的 Base String經HMAC-SHA1算法計算得出。

第一步,準備base string(使用上文提到的方法)
POST&https://api.t.sina.com.cn/oauth/access_token&oauth_consumer_key=GDdmIQH6jhtmLUypg82g&oauth_nonce=9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1272323047&oauth_token=8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc&oauth_verifier=pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY&oauth_version=1.0
接着將consumer_secret和oauth_token_secret連接起來,中間用&分割(這是準備密鑰的方法,下面還會用到):
MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98&x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA
生成的OAuth簽名如下:
PUw/dHA4fnlJYM6RhXk5IU/0fCc=
然後向給定的url發送請求,請求頭部一定要包含request token,request頭部如下:
OAuth oauth_nonce="9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8", 
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1272323047",
oauth_consumer_key="GDdmIQH6jhtmLUypg82g", oauth_token="8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc", oauth_verifier="pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY", oauth_signature="PUw/dHA4fnlJYM6RhXk5IU/0fCc=",
oauth_version="1.0"
新浪微博開放平臺會返回應用需要的信息,包括用戶名,oauth_token/oaut_token_secret(當然這裏就是access token了)。response內容如下:
oauth_token=819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw&oauth_token_secret=J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA&
user_id=819797&
screen_name=openapi
現在就可以使用access token來發布信息了。

獲取用戶信息

按用戶ID或暱稱返回用戶資料以及用戶的最新發布的一條微博消息。
請求參數:
必選 類型及範圍 說明
source true string 申請應用時分配的AppKey,調用接口時候代表應用的唯一身份。(採用OAuth授權方式不需要此參數)
:id false int64/string 用戶ID(int64)或者暱稱(string)。該參數爲一個REST風格參數。調用示例見注意事項
user_id false int64 用戶ID,主要是用來區分用戶ID跟微博暱稱。當微博暱稱爲數字導致和用戶ID產生歧義,特別是當微博暱稱和用戶ID一樣的時候,建議使用該參數
screen_name false string 微博暱稱,主要是用來區分用戶UID跟微博暱稱,當二者一樣而產生歧義的時候,建議使用該參數
:id、user_id、screen_name這三個參數三者至少要提供一個

接下來,就可以進行用戶驗證(如果驗證成功,將會返回用戶的詳細信息)了。以下是進行用戶驗證的相關參數:
oauth_consumer_key - GDdmIQH6jhtmLUypg82g
oauth_nonce - oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y
oauth_signature_method - HMAC-SHA1
oauth_token - 819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw
oauth_timestamp - 1272325550
oauth_version - 1.0
使用BASE STRING生成算法:
POST&http://api.t.sina.com.cn/account/verify_credentials&oauth_consumer_key=GDdmIQH6jhtmLUypg82g&oauth_nonce=9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1272325550&oauth_token=819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw&oauth_verifier=pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY&oauth_version=1.0
然後將oauth_comsumer_secret和oauth_token_secret以&作爲分隔符拼起來。將拼接後的字符串作爲簽名的KEY進行加密,生成簽名。
key如下:
MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98&J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA
生成的簽名如下:
ICuKVLKetCO4axEppJBqOofFg/A=
接下來就可以通過http發送請求,生成的http header如下:
OAuth oauth_nonce="oElnnMTQIZvqvlfXM56aBLAf5noGD0AQR3Fmi7Q6Y", 
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1272325550",
oauth_consumer_key="GDdmIQH6jhtmLUypg82g",
oauth_token="819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw", oauth_signature="ICuKVLKetCO4axEppJBqOofFg/A=",
oauth_version="1.0"
響應如下:
{ weibo=null, 
id=1803876591,
name='loopa',
screenName='loopa',
location='北京 海淀區',
description='2fBAcRG0]8OGRvp',
profileImageUrl='http://tp4.sinaimg.cn/1803876591/50/0',
url='',
isProtected=false,
followersCount=23,
statusCreatedAt=Mon Sep 27 13:50:14 CST 2010,
statusId=2847344825, statusText='uhYFQJ[',
statusSource='<a href="" rel="nofollow">微博開放平臺接口</a>',
statusTruncated=false,
statusInReplyToStatusId=0,
statusInReplyToUserId=0,
statusFavorited=false,
statusInReplyToScreenName='',
profileBackgroundColor='',
profileTextColor='',
profileLinkColor='',
profileSidebarFillColor='',
profileSidebarBorderColor='',
friendsCount=1,
createdAt=Fri Aug 27 00:00:00 CST 2010,
favouritesCount=0,
utcOffset=-1,
timeZone='',
profileBackgroundImageUrl='',
profileBackgroundTile='',
following=false,
notificationEnabled=false,
statusesCount=8509,
geoEnabled=false,
verified=false }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章