分類  >  綜合 >

對OAuth1.0協議的懂得

tags:    時間:2014-05-04 18:54:02
對OAuth1.0協議的理解

OAuth(開放授權)是一個開放標準,允許用戶讓第三方應用訪問該用戶在某一網站上存儲的私密的資源(如照片,視頻,聯繫人列表),而無需將用戶名和密碼提供給第三方應用。協議地址為:http://oauth.net/core/1.0/#rfc.section.A.5

研究的是OAuth1.0,因為2.0褒貶不一,連創始人都宣布脫離關係了。。。而1.0基本各個大網站都支持的不錯

具體舉個例子:

比如我們手機用蝦米app來聽歌,想要登錄蝦米但又不想註冊一個新的賬號,可以選擇第三方登錄,也就是用微博號登錄。那麼自然不能直接把微博的用戶名密碼告訴蝦米,不然誰知道會發生什麼事情呢?所以就用到了OAuth. 蝦米將頁面轉到新浪提供的登錄頁面,我們在新浪登錄頁面輸入用戶名和密碼,進行身份驗證,然後新浪會給蝦米一個token,如下(僅供參考格式,不要在意值是多少。。。):

oauth_consumer_key="0685bd9184jfhq22",                 oauth_token="ad180jjd733klru7",                 oauth_signature_method="HMAC-SHA1",                 oauth_signature="wOJIO9A2W5mFwDgiDvZbTSMK%2FPY%3D",                 oauth_timestamp="137131200",                 oauth_nonce="4572616e48616d6d65724c61686176",                 oauth_version="1.0"
之後的各種操作就可以利用以上的各個變數來進行身份驗證,這樣蝦米也不知道用戶的用戶名和密碼,但是可以利用微博賬號來作為新的用戶身份。

注意:token指的是上面所有內容,包含所有的key-value,而oauth_token則是指token裡面的一項,用於唯一標識用戶。這點我之前矛盾了很久,到底說的token和oauth_token有沒有區別。。。

下面具體來講oauth身份認證的幾個步驟(結合之前的例子):

0)首先第三方app一定要去相應的網站註冊。如上面的例子中,第三方式蝦米app,resource owner是新浪微博,也就是蝦米需要告訴新浪微博我要來使用你裡面的數據,所以註冊一下跟你說一聲,這樣蝦米app會得到新浪微博返回的一個consumer_key和consumer_secret. 這兩個也就是蝦米app在新浪微博的一個身份,用戶名+密碼(當然為了安全,密碼應該是通過郵件等方式發送給蝦米app的)。這第0步不是每次身份認證都要用的,只是在app開發時,開發者需要做這一步而已。

1)蝦米app向新浪微博申請要一個token,說我打算訪問你的數據啦。申請的時候蝦米app發送如下的http請求給新浪微博:

注意申請token的網址是:http://api.t.sina.com.cn/oauth/request_token

consumer secret - "MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98" oauth_callback - http://localhost:3005/the_dance/process_callback?service_provider_id=11 oauth_consumer_key - GDdmIQH6jhtmLUypg82g oauth_nonce - QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk oauth_signature_method - HMAC-SHA1 oauth_timestamp - 1272323042 oauth_version - 1.0
注意注意:第一個consumer secret並不是http裡面的內容,這是之後用來生成簽名的(因為oauth1.0是針對http設計的,故傳遞secret不安全,所以採用簽名機制)。解釋一下幾個變數的含義:這裡的secret就是指第0步註冊后得到的蝦米app的密碼。callback是指我認證後轉回哪個頁面,總不能老是停在微博頁面吧,consumer_key就是剛才第0步得到的,nonce是number used once(具體形式有多種,可以數字可以字元串),只要知道是和timestamp搭配來標識唯一就行了(防止一些攻擊),signature_method是產生簽名的方法,一般用HMAC-SHA1, timestamp一反面和nonce唯一標識token,另一方面用來保證token的實效性,version表示oauth版本。

然後我們利用上述信息產生一個base string,如下(產生方法是http方法(get或者post)+網址(這裡指新浪微博網址)+上述各值):

POST&https%3A%2F%2Fapi.t.sina.com.cn%2Foauth%2Frequest_token&oauth_callback%3Dhttp%253A%252F%252Flocalhost%253A3005%252Fthe_dance%252Fprocess_callback%253Fservice_provider_id%253D11%26oauth_consumer_key%3DGDdmIQH6jhtmLUypg82g%26oauth_nonce%3DQP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1272323042%26oauth_version%3D1.0
由於我們還未獲取到oauth_token和oauth_token_secret,所以我們的BASE STRING里沒有包含oauth_token和oauth_token_secret。

這個時候剛才提過的consumer_key就發揮作用了,用consumer_key作為key對base string進行HMAC-SHA1簽名,假設得到簽名為「8wUi7m5HFQy76nowoCThusfgB+Q=」,則我們的http請求如下:

oauth_nonce="QP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk", oauth_callback="http%3A%2F%2Flocalhost%3A3005%2Fthe_dance%2Fprocess_callback%3Fservice_provider_id%3D11", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1272323042", oauth_consumer_key="GDdmIQH6jhtmLUypg82g", oauth_signature="8wUi7m5HFQy76nowoCThusfgB%2BQ%3D", oauth_version="1.0"
然後新浪那邊利用我們傳過去的這些信息對app進行身份驗證,即在此利用上述信息產生簽名,核對簽名(因為新浪微博是有蝦米app註冊時的密碼的,這樣就達到了不用傳遞密碼的效果,保證安全),如果app身份正確,則返回如下內容:

oauth_token=8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc&oauth_token_secret=x6qpRnlEmW9JbQn4PQVVeVG8ZLPEx6A0TOebgwcuA
即返回一個oauth_token和oauth_token_secret

2)由於上述token只是一個臨時token,蝦米app需要用戶授權

授權的網址是:http://api.t.sina.com.cn/oauth/authorize

蝦米app會將頁面轉到授權網址,並攜帶oauth_token參數,如下:

http://api.t.sina.com.cn/oauth/authorize?oauth_token=8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc

然後需要用戶輸入他在新浪微博的用戶名和密碼,正確后新浪微博返回以下結果(注意verifier是1.0a加入的,為了解決OAuth Session Fixation Attack):

oauth_token=8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc&oauth_verifier=pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY 

3)第三步蝦米app用上述信息去把之前的臨時token變成access token(可以訪問資源的token)

網址為:http://api.t.sina.com.cn/oauth/access_token
目前已有信息為:
oauth_consumer_key - GDdmIQH6jhtmLUypg82g     oauth_nonce - 9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8     oauth_signature_method - HMAC-SHA1     oauth_token - 8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc     oauth_timestamp - 1272323047     oauth_verifier - pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY     oauth_version - 1.0
和第一步一樣,利用上述信息產生一個base string,如下:
POST&https%3A%2F%2Fapi.t.sina.com.cn%2Foauth%2Faccess_token&oauth_consumer_key%3DGDdmIQH6jhtmLUypg82g%26oauth_nonce%3D9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1272323047%26oauth_token%3D8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc%26oauth_verifier%3DpDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY%26oauth_version%3D1.0
然後接著進行簽名,這裡的key為oauth_consumer_secret+oauth_token_secret,兩者拼接成一個key,對上述base string進行簽名。得
「PUw/dHA4fnlJYM6RhXk5IU/0fCc=」,於是發送的http請求如下:
oauth_nonce="9zWH6qe0qG7Lc1telCn7FhUbLyVdjEaL3MO5uHxn8", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1272323047", oauth_consumer_key="GDdmIQH6jhtmLUypg82g", oauth_token="8ldIZyxQeVrFZXFOZH5tAwj6vzJYuLQpl0WUEYtWc", oauth_verifier="pDNg57prOHapMbhv25RNf75lVRd6JDsni1AJJIDYoTY", oauth_signature="PUw%2FdHA4fnlJYM6RhXk5IU%2F0fCc%3D", oauth_version="1.0"
然後新浪微博伺服器端再次利用簽名技術,對此進行身份驗證,正確的話則返回:
oauth_token=819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw&oauth_token_secret=J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA&user_id=819797&screen_name=openapi
那麼這裡的oauth_token就是access token了,secret也就是access token的密碼

4)蝦米app利用access token就可以訪問用戶資源了,還是像上述一樣,利用access token構造簽名,然後申請資源,伺服器驗證身份后,返回用戶的資料(比如微博頭像等等),就不重複講了


總結:oauth1.0分成3步:1)request token 2) authorize token 3) access token

優點:利用簽名技術保證安全

缺點:太過繁雜,不過貌似是由於http不安全只能設計成這樣。。。

嗯,暫時就先說到這裡吧。。。

推薦閱讀文章

Bookmark the permalink ,來源:互聯網