轉自:http://blog.csdn.net/yangjian8915/article/details/11816669算法
官方的流程圖以下:api
下面開始一步步講解,如何獲取最終的access_token與access_token_secret,注:認證的全過程都是經過發送http GET/POST進行的:安全
1. 首先經過第三方應用,獲取其應用的oauth_consumer_key與oauth_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_key與oauth_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_token與access_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_token與oauth_token_secret即咱們最終須要的access_token與access_token_secret。user_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_method,HMAC-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請求,能夠拿它來驗證本身的每次請求。