twitter 受權過程

轉自:http://blog.csdn.net/yangjian8915/article/details/11816669算法

官方的流程圖以下:api

 

下面開始一步步講解,如何獲取最終的access_tokenaccess_token_secret,注:認證的全過程都是經過發送http GET/POST進行的:安全

 

1.    首先經過第三方應用,獲取其應用的oauth_consumer_keyoauth_consumer_secret,這一對是由第三方應用提供的,固然,本身也能夠經過twitter帳戶申請本身的應用,這樣就有了key/secret。服務器

2.       使用http://api.twitter.com/oauth/request_token獲取未受權的token:session

2.1.       使用GET方法工具

2.2.       使用的參數是圖中A標識的列表:oauth_consumer_key,oauth_signature_method,oauth_signature,oauth_timestamp,oauth_nonce,oauth_version.(因爲不是Web應用,故不須要oauth_callback)編碼

2.3.       如何構造每一個參數:加密

2.3.1.  oauth_consumer_key,從第三方應用程序得到的url

2.3.2.  oauth_signature_method,簽名方法,有3種:HMAC-SHA1,RSA-SHA1, PLAINTEXT,因爲twitter只支持HMAC-SHA1,故此參數值固定,爲HMAC-SHA1spa

2.3.3.  oauth_signature,簽名(此參數容易錯,稍後再談)

2.3.4.  oauth_timestamp,時間戳,根據1970-1-1 0:0:0到如今所通過的秒數,如1280817414

2.3.5.  oauth_nonce,隨機字符串,注意,每次此參數都必需要不同的,例如3d1sdf34

2.3.6.  oauth_version,可選參數,目前版本是1.0,故值固定爲1.0,但爲方便擴展,最好加上

 

2.4.       最終以url?{參數名=參數值,&}格式發送出去,此處我給出個人發送串,參數順序隨便,但簽名時有要求

http://api.twitter.com/oauth/request_token?oauth_consumer_key=gReNivhwQsHJ8401DYGtAw&oauth_nonce=1234abcd1234&oauth_signature=TrKrYdCxmpWdLeZBrifNg5HBGFw%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1280818011&oauth_version=1.0

2.5.       如圖中B所示,成功發送後會獲得返回的值未受權的oauth_token, oauth_token_secret (第三個只要是true就好了),個人返回串以下:

oauth_token=1SXf0MSsj8HcZffAma1pnHhbG1rzbXSmlh4deChw8&oauth_token_secret=CYoxvrSNX5IT1O02QrPydK3peZ0oRRvvvRkyMVBLTU&oauth_callback_confirmed=true

3.       使用http://api.twitter.com/oauth/authorize進行確認

3.1.       使用GET方法

3.2.       使用的參數爲:

3.2.1.       oauth_consumer_key,從第三方應用程序得到的

3.2.2.       oauth_nonce,隨機字符串,注意,每次都不同

3.2.3.       oauth_signature_method,簽名方法,同上,只能是HMAC-SHA1

3.2.4.       oauth_signature,簽名,(容易出錯,後面說)

3.2.5.       oauth_timestamp,時間戳,必定要比上一次的大

3.2.6.       oauth_token,未受權的token,即步驟2返回的第一個值

3.2.7.       oauth_version,同上,1.0

3.3.       最終以url?{參數名=參數值,&}格式發送出去,此處我給出個人發送串,參數順序隨便,但簽名時有要求

http://api.twitter.com/oauth/authorize?oauth_consumer_key=gReNivhwQsHJ8401DYGtAw&oauth_nonce=14234ab12234&oauth_signature=1zR5E6gH7RSlmjT3uUL2EeMBzuE%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1280819022&oauth_token=1SXf0MSsj8HcZffAma1pnHhbG1rzbXSmlh4deChw8&oauth_version=1.0

3.4.       成功返回後,是HTML代碼(因爲較多,我只展現顯示的結果),將它顯示出來即:

此截圖對應流程圖所示C到D的過程當中,須要真正的twitter用戶(應用程序擁有者用戶也能夠)進行確認,是否容許本身的帳戶被名爲XXX的應用訪問(其標識便是oauth_consumer_keyoauth_consumer_secret),而且輸入twitter帳號與密碼,進行allow或者deny。

而咱們要作的就是解析HTML代碼(其實只須要解析出其中的一個字串便可),而後經過POST來模擬Allow的按鈕提交,這樣就不須要瀏覽這個頁面了。先解析出來,HTML中必包含一行:

<input name="authenticity_token"type="hidden" value="98d562c5c67cd90a56e7da4c6bdef28b4c8fe6b2"/>

 

4.       仍然使用http://api.twitter.com/oauth/authorize獲取確認碼(PIN)。

4.1.       使用POST方法

4.2.       使用的參數爲:

4.2.1.       authenticity_token,值爲解析出來的98d562c5c67cd90a56e7da4c6bdef28b4c8fe6b2

4.2.2.       oauth_token,未受權token,即步驟2返回的第一個值

4.2.3.       session[username_or_email],用戶名,如myusername

4.2.4.       session[password],密碼,如 mypassword

4.3.       最終POST http://api.twitter.com/oauth/authorize,POST的數據爲

authenticity_token=98d562c5c67cd90a56e7da4c6bdef28b4c8fe6b2&oauth_token=1SXf0MSsj8HcZffAma1pnHhbG1rzbXSmlh4deChw8&session[username_or_email]= myusername&session[password]= mypassword

4.4.       返回成功結果仍然是HTML代碼(因爲較多,我只展現顯示的結果),將它顯示出來即:

此截圖對應的是流程圖中的標識D,上面的確認碼(PIN),即爲oauth_verifier

而咱們要作的就是,解析HTML(也就是獲取上面的數字字符串),HTML中僅有這麼一個字段:

<divid="oauth_pin">

 3638897

</div>

其中oauth_pin是惟一的,因此能夠經過它來提取確認碼。

5.       使用http://api.twitter.com/oauth/access_token用已受權的token與PIN碼換取咱們開頭的最終目標:access_tokenaccess_token_secret

5.1.       使用GET方法

5.2.       使用的參數是圖中E標識的列表:oauth_consumer_key,request_token,oauth_signature_method,oauth_signature,oauth_timestamp,oauth_nonce,oauth_version,oauth_verifier

5.3.       如何構造每一個參數:

5.3.1.  oauth_consumer_key,從第三方應用程序得到的

5.3.2.  request_token,步驟2獲得的

5.3.3.  oauth_signature_method,仍然是HMAC-SHA1

5.3.4.  oauth_signature,簽名,(容易出錯,後面說)

5.3.5.  oauth_timestamp,時間戳,必定要比上次大

5.3.6.  oauth_nonce,隨機串,每次要不同

5.3.7.  oauth_version,版本號,固定爲1.0

5.3.8.  oauth_verifier,步驟4獲得的PIN碼,即3638897

5.4.       最終以url?{參數名=參數值,&}格式發送出去,此處我給出個人發送串,參數順序隨便,但簽名時有要求

http://api.twitter.com/oauth/access_token?oauth_consumer_key=gReNivhwQsHJ8401DYGtAw&oauth_nonce=3654cf32ds2f&oauth_signature=aHEXqn2nu%2BRCszMp9P5BqJTpu4o%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1280821505&oauth_token=1SXf0MSsj8HcZffAma1pnHhbG1rzbXSmlh4deChw8&oauth_verifier=3638897&oauth_version=1.0

5.5.       成功返回,得到

oauth_token=169731880-OzvV2F9vWN2HwztmJi7HAvsOM78pU7Xc2dg4ZZX2&oauth_token_secret=0BQFkAcOqYGNgbt0NwoF7w3G9MUlt9AkSJBIwkxoFA&user_id=15834158&screen_name=mytesttwitter

此結果對應流程圖中的標識F,其中oauth_tokenoauth_token_secret即咱們最終須要的access_tokenaccess_token_secretuser_id是用戶的ID號,頗有用,不少API都須要用本身的ID號做爲參數;screen_name是屏顯名字,有些API也須要它做爲參數

至此,咱們的OAuth認證過程徹底結束。

 

6.    使用access_token與access_token_secret進行調用API,而不須要用戶名與密碼,咱們此處試着調用http://api.twitter.com/1/statuses/home_timeline.xml來獲取用戶的timeline。

6.1.       使用GET方法

6.2.       使用的參數是圖中G標識的列表:oauth_consumer_key,oauth_token,oauth_signature_method,oauth_signature,oauth_timestamp,oauth_nonce,oauth_version

6.2.1.  oauth_consumer_key,從第三方應用程序得到的

6.2.2.  oauth_token,即access_token,步驟5獲得的

6.2.3.  oauth_signature_methodHMAC-SHA1

6.2.4.  oauth_signature,簽名,(容易出錯,後面說)

6.2.5.  oauth_timestamp,時間戳,每次要比上一次的大

6.2.6.  oauth_nonce,隨機串,每次要不同

6.2.7.  oauth_version,版本號,1.0

6.3.       最終以url?{參數名=參數值,&}格式發送出去,此處我給出個人發送串,參數順序隨便,但簽名時有要求

http://api.twitter.com/1/statuses/home_timeline.xml?oauth_consumer_key=gReNivhwQsHJ8401DYGtAw&oauth_nonce=365fd4ff32ffddffs2f&oauth_signature=MxEA2lODZ5QQh8icOL8z8f1PNOQ%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1280822863&oauth_token=169731880-OzvV2F9vWN2HwztmJi7HAvsOM78pU7Xc2dg4ZZX2&oauth_version=1.0

6.4.       成功返回後便可獲得相應xml格式的timeline

 

7.    簽名方法

7.1.       背景:Twitter使用的是HMAC-SHA1方法進行簽名,在以上1-5認證的步驟中,有2,3,5須要簽名。而在使用API時,只要須要認證的API,都須要進行簽名,方可成功調用。

7.2.       原理:OAuth認證經過用戶在調用API時自行簽名的結果,與API一塊兒發送到服務器,服務器再用相同的方法進行簽名,將結果與咱們傳過去的結果相比較,若是相同,那麼簽名經過,咱們每次的隨機串與時間戳都不同,因此防止了重放攻擊,同時這個過程當中沒有透露用戶的帳號與密碼,加強了帳號安全性。

7.3.       方法:簽名須要簽名串(text)與密鑰(key)

7.3.1.  簽名串(text)的構成:HttpMethod&url&參數。三個紅色串必須用urlencode進行編碼編碼中的%xx符號,xx中的字母必須爲大寫

其中HttpMethod爲GET/POST/PUT/DELETE等http方法之一,必須全爲大寫,編碼後仍爲自己

url爲不帶參數的url,如http://api.twitter.com/1/statuses/home_timeline.xml,必須全爲小寫,編碼後的結果爲http%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fhome_timeline.xml

參數這次請求中的除了oauth_signature之外的全部參數,包括一些API所要求的參數,好比在更新本身狀態時,須要status參數。格式爲按照[參數名=參數值]的格式中間用&隔開,而且要按照字母順序升序排列,若是參數名相同,那麼按照參數值的字母順序升序排列。如

oauth_consumer_key=gReNivhwQsHJ8401DYGtAw&oauth_nonce=df563232s&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1280824014&oauth_token=169731880-OzvV2F9vWN2HwztmJi7HAvsOM78pU7Xc2a4sZZX2&oauth_version=1.0

編碼後爲

oauth_consumer_key%3DgReNivhwQsHJ8401DYGtAw%26oauth_nonce%3Ddf563232s%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1280824014%26oauth_token%3D169731880-OzvV2F9vWN2HwztmJi7HAvsOM78pU7Xc2dg4ZZX2%26oauth_version%3D1.0

 

那麼將三者再用&組合起來後,即爲

GET&http%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fhome_timeline.xml&

oauth_consumer_key%3DgReNivhwQsHJ8401DYGtAw%26oauth_nonce%3Ddf563232s%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1280824014%26oauth_token%3D169731880-OzvV2F9vWN2HwztmJi7HAvsOM78pU7Xc2dg4ZZX2%26oauth_version%3D1.0

注意,這個是1個字符串,上面因爲縮進不夠,因此換了行。這樣,簽名串(text)就構造好了。

 

7.3.2.密鑰(key)的構成:oauth_consumer_secret&oauth_token_secret

其中

oauth_consumer_secret即從第三方應用程序得到的。

oauth_token_secret在步驟2時還沒得到,那麼即爲空,但&得保留;在步驟三、5時,因爲在步驟2得到了未受權的token與token_secret,此時就用未受權的token_secret;步驟6以及後續全部的API調用時,就用得到的最終的access_token_secret,之後也永遠用這個,除非從新認證。

例如:

在步驟2中,key就是:

gReNivhwQsHJ8401DYGtAw&

在步驟三、5中,key就是:

gReNivhwQsHJ8401DYGtAw&CYoxvrSNX5IT1O02QrPydK3peZ0oRRvvvRkyMVBLTU

在步驟6及之後的調用中,key就是:

gReNivhwQsHJ8401DYGtAw&0BQFkAcOqYGNgbt0NwoF7w3G9MUlt9AkSJBIwkxoFA

這樣,密鑰(key)就構造好了。

 

7.4.       生成signature – signature也要用url encode進行編碼

本身用程序實現HMAC-SHA1的加密簽名算法。下面給個利用上面的text/key結果,用HMAC-SHA1算法生成的signature,你也能夠經過這個來判斷本身的算法正不正確。

Text:

GET&http%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fhome_timeline.xml&

oauth_consumer_key%3DgReNivhwQsHJ8401DYGtAw%26oauth_nonce%3Ddf563232s%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1280824014%26oauth_token%3D169731880-OzvV2F9vWN2HwztmJi7HAvsOM78pU7Xc2dg4ZZX2%26oauth_version%3D1.0

Key:

gReNivhwQsHJ8401DYGtAw&0BQFkAcOqYGNgbt0NwoF7w3G9MUlt9AkSJBIwkxoFA

生成的signature:

ITtbuTI901ie4bCFg5vGfb1mCxM=

最後,生成的signature也要用url encode進行編碼,編碼後的結果爲

ITtbuTI901ie4bCFg5vGfb1mCxM%3D

此時再將此字串填充到要發送的http請求中便可。

 

後記:

1.在認證過程當中未得到最終的access_token/key以前的那個未受權的oauth_token在使用時是有有效期的,應該是幾分鐘以內,由於在編寫此文檔時,每次回頭繼續時都超時了,因此後面的幾個步驟我都是從新申請的,並且每次生成的都不同,但爲了統一,我就將後面的幾回oauth_token又換回到第一次申請到的,僅爲方便理解。

2.認證的過程全貌在此,主要容易錯的地方就是簽名,最好反覆對照簽名方法,及上面的認證步驟,加深理解。

3.最後,介紹一個工具,http://developer.netflix.com/resources/OAuthTest

能夠直接生成已簽名的http請求,能夠拿它來驗證本身的每次請求。

相關文章
相關標籤/搜索