我們首先來認識一下OAuth協議吧,這個東西很早就聽說過,總覺得離我很遠(我的項目用不到這些),但是最近不得不學習一下了。我在網上找了一些解釋,認為解釋的最好的是這樣說的(出處:http://hi.baidu.com/powerthinks/item/f1cb9b3c7a88251c9dc65efa)
如果你開車去酒店赴宴,你經常會苦於找不到停車位而耽誤很多時間。是否有好辦法可以避免這個問題呢?有的,聽說有一些豪車的車主就不擔心這個問題。豪車一般配備兩種鑰匙:主鑰匙和泊車鑰匙。當你到酒店后,只需要將泊車鑰匙交給服務生,停車的事情就由服務生去處理。與主鑰匙相比,這種泊車鑰匙的使用功能是受限制的:它只能啟動發動機並讓車行駛一段有限的距離,可以鎖車,但無法打開后備箱,無法使用車內其他設備。這里就體現了一種簡單的“開放授權”思想:通過一把泊車鑰匙,車主便能將汽車的部分使用功能(如啟動發動機、行駛一段有限的距離)授權給服務生。
授權是一個古老的概念,它是一個多用戶系統必須支持的功能特性。比如,Alice和Bob都是Google的用戶,那么Alice應該可以將自己的照片授權給Bob訪問。但請注意到,這種授權是一種封閉授權,它只支持系統內部用戶之間的相互授權,而不能支持與其他外部系統或用戶之間的授權。比如說,Alice想使用“網易印像服務”將她的部分照片沖印出來,她怎么能做到呢?
肯定有人會說,Alice可以將自己的Google用戶名和密碼告訴網易印像服務,事情不就解決了嗎?是的,但只有毫不關注安全和隱私的同學才會出此“絕招”。那么我們就來想一想,這一“絕招”存在哪些問題?
(1) 網易印像服務可能會緩存Alice的用戶名和密碼,而且可能沒有加密保護。它一旦遭到攻擊,Alice就會躺着中槍。
(2) 網易印像服務可以訪問Alice在Google上的所有資源,Alice無法對他們進行最小的權限控制,比如只允許訪問某一張照片,1小時內訪問有效。
(3) Alice無法撤消她的單個授權,除非Alice更新密碼。
在以Web服務為核心的雲計算時代,像用戶Alice的這種授權需求變得日益迫切與興盛,“開放授權(Open Authorization)”也正因此而生,意在幫助Alice將她的資源授權給第三方應用,支持細粒度的權限控制,並且不會泄漏Alice的密碼或其它認證憑據。
上面的例子寫的通俗易懂,各位一看就明白了,后面作者還附了一個這樣圖,以及注釋:
從引言部分的描述我們可以看出,OAuth的參與實體至少有如下三個:
· RO (resourceowner): 資源所有者,對資源具有授權能力的人。如上文中的用戶Alice。
· RS (resourceserver): 資源服務器,它存儲資源,並處理對資源的訪問請求。如Google資源服務器,它所保管的資源就是用戶Alice的照片。
· Client: 第三方應用,它獲得RO的授權后便可以去訪問RO的資源。如網易印像服務。
此外,為了支持開放授權功能以及更好地描述開放授權協議,OAuth引入了第四個參與實體:
· AS(authorization server): 授權服務器,它認證RO的身份,為RO提供授權審批流程,並最終頒發授權令牌(Access Token)。讀者請注意,為了便於協議的描述,這里只是在邏輯上把AS與RS區分開來;在物理上,AS與RS的功能可以由同一個服務器來提供服務。
如圖1所示,協議的基本流程如下:
(1) Client請求RO的授權,請求中一般包含:要訪問的資源路徑,操作類型,Client的身份等信息。
(2) RO批准授權,並將“授權證據”發送給Client。至於RO如何批准,這個是協議之外的事情。典型的做法是,AS提供授權審批界面,讓RO顯式批准。這個可以參考下一節實例化分析中的描述。
(3) Client向AS請求“訪問令牌(AccessToken)”。此時,Client需向AS提供RO的“授權證據”,以及Client自己身份的憑證。
(4) AS驗證通過后,向Client返回“訪問令牌”。訪問令牌也有多種類型,若為bearer類型,那么誰持有訪問令牌,誰就能訪問資源。
(5) Client攜帶“訪問令牌”訪問RS上的資源。在令牌的有效期內,Client可以多次攜帶令牌去訪問資源。
(6) RS驗證令牌的有效性,比如是否偽造、是否越權、是否過期,驗證通過后,才能提供服務。
雖然上面的例子舉的很好,圖畫的也很清楚,可是對於我這種愚鈍的人,還是理解了半天,請允許我在此狗尾續貂一次吧:
其實上面的圖就如同這樣一個故事
1、我的一個同事小張(Client),向我或者公司(RO)借錢,他會給我說:“借給我2000元,可以嗎?”(也就是說向我請求一個有限的資源,就是Authorization Request);
2、這時我肯定不會把我的銀行卡給他,並告訴他密碼,我要用到OAuth。首先我會說“好的”,並且給他寫一個條,上面寫着“允許小張借款2000元”的請求(Authorization Grant);
3、小張拿着我寫的條(AuthorizationGrant),給財務總監(AS);
4、財務總監看到我的條后會給小張一個提款單(Access Token),上面寫着請出納給小張支出2000元的借款。
5、小張拿到了提款單(AccessToken)到出納那里,按照公司的規定,出納只有看到了財務總監給的提款單(Access Token),才能過支出錢,這是出納核對后,小張就順利的拿到了2000元錢(Protected Resource)。
根據上面的故事我們來說已說OAuth的特點:
1、小張不可能知道,我或者公司總共有多少錢;
2、我也保護了賬戶的密碼,維護的公司的制度;
3、就像現實中一樣,財務總監和出納一般都在一起辦公,而AS和RS一般也會在同一個服務器上;
4、按照同樣的公司制度(也就是OAuth),其他人不管誰來支出錢都要這樣,我只需要保證制度執行的嚴密,其他任何人都不會知道我的帳務信息了。
這也就是OAuth全稱--- OpenAuthorization(開放式授權)的意義了。
下面我來看看為微信中是如何實現這個過程的,我引用了方倍工作室教程里面的圖(http://www.cnblogs.com/txw1958/p/weixin71-oauth20.html):
在這個途中User就是我例子中的小張,APP就是我,Auth_svr就是財務總監和出納。
如果我使用微信中的官法提法因該這么說:
1、小張向我提出訪問,訪問過程涉及以下參數:
也就是要知道我的APPID:其實就是我的名字;redirect_uri:到財務那里怎么走;response_type:知道我想我要批條(請填寫code);scope批條的類別(后面會介紹到);state:到財務那里帶些什么(參數)。
2、我同意了他的要求
也就是微信幫助提到的“如果用戶同意授權,頁面將跳轉至 redirect_uri/?code=CODE&state=STATE。”也就是我給了小張一個批條(code),告訴小張去財務的路,以及到那里需要帶些什么。
3、小張拿着我的批條到財務總監那里得到提款單
小張拿着我的批條(code),按照“redirect_uri/?code=CODE&state=STATE”這個路徑去財務那里“通過code換取網頁授權access_token”
上圖可以知道我還可以獲得OPENID!這個是非常重要的,前一章提到了它的用處,微信在這里還特別強調了“獲取用戶基本信息接口是在用戶和公眾號產生消息交互時,才能根據用戶OpenID獲取用戶基本信息,而網頁授權的方式獲取用戶基本信息,則無需消息交互,只是用戶進入到公眾號的網頁,就可彈出請求用戶授權的界面,用戶授權后,就可獲得其基本信息(此過程甚至不需要用戶已經關注公眾號。)”
4、小張拿到了提款單又到出納那里提款
得到了access_token后,拉取用戶信息,也就是“通過access_token和openid拉取用戶信息了。”
最終得到是如下的信息:
本來就此已經說完了,不過不少研發人員可能還是會有疑問:“費這么半天勁,不就得到了個用戶的基本信息嘛,我通過其他方式也可以得到!”。
其實不然,這還是非常有用的:
第一,這是唯一一個重不需要關注你的微信好就可獲得用戶信息的辦法;
第二,我們來設想一下下面場景:如果我們開發一個系統想過沒想過不要用戶名和密碼了?用戶登錄,並授權以后,進入我們的系統,我系統里面存放着這個微信號(OPENID)對應的權限的功能。這樣我再也不用擔心用戶忘記密碼或者密碼泄露的事情了,因為這些事情微信已經幫助給做了。說到這里可能你還會問:“那豈不是每個人必須有微信號”,我先不說這里我們做的就是微信平台的應用,也不說騰訊有多大的野心,這種OAuth協議已經在微博,google,baidu,郵箱等廣泛應用,我做他們響應的接口,你就說一個上用你系統的人,沒有微信還不能有微博,google,baidu這些帳號,沒有這些帳號你還能沒有個郵箱?這些我覺得因該是以后的趨勢。
何況,隨着微信的完善,以后或許我們拿到的不僅是用戶的基本信息,還有用戶朋友圈的帖子,圖片,用戶的喜好等等,這些都為我們新開發的系統提供了有效的可分析的數據!