OAuth2.0是一套標准.
一、問題
-
這個標准解決了這樣的一個問題.
允許用戶讓第三方應用訪問該用戶在某一網站上存儲的私密的資源(如照片,視頻,聯系人列表),而無需將用戶名和密碼提供給第三方應用。
第三方應用–比如一個繪圖的小軟件”paint”
用戶–比如”我的qq空間賬號ws”
私密信息–比如我qq空間中的照片
資源服務方-qq空間
認證服務器-qq空間 -
正常情況下,要訪問用戶ws的qq中的照片, 需要將賬號和密碼發送到qq空間的認證服務器驗證身份.
但是第三方應用要訪問, 怎么辦呢?
把賬號密碼告訴第三方應用paint,肯定不行
這就相當於把密碼告訴別人,而且還是我不認識的人.不安全.
paint只需要一個照片,但把密碼都給他了,他連我的日記都能看了.
paint如果把密碼公開或者泄露給別人的,那我怎么辦.
二、解決
-
OAuth2.0是怎么解決的呢?
給第三方應用paint一個臨時密碼,過期作廢,而且這個密碼的訪問權限可由我隨時取消.這樣就足夠安全了.
這個臨時密碼就是access_token.
當然發放access_token的方法就多種多樣了,這些方法叫做授權模式 -
授權模式一共四種:
1.客戶端模式(Client Credentials)
2.密碼模式(User Credentials)
3.簡化模式(Implicit)
4.授權碼模式(Authorization Code)
三、授權模式
1.客戶端模式(Client Credentials)
這是最簡單的一種方式, 不需要得到用戶ws授權,只要資源服務方qq空間對第三方應用paint發放一個client_id和client_secret, 第三方應用訪問資源時通過剛才的id和secret進行驗證后即返回access_token.
當然,這樣對用戶ws有些不公平,但實際上,在第三方應用paint所訪問的資源與用戶ws關系不大時就比較方便了.
此時,paint能從qq空間獲取任意圖片,只需要向qq空間認證,因為這些圖片與具體某個用戶無關.
2.密碼模式(User Credentials)
用戶ws將自己的用戶名密碼直接告知第三方應用paint, paint即可使用這個密碼向資源服務方qq空間獲取圖片.
這個方法就是剛才說過的很不安全的方法.但仍然有其適用的范圍.
就是在用戶ws與第三方應用paint更相熟情況, 也就是ws完全信任paint,放心的把密碼交給paint使用.
此時,paint僅能獲取用戶ws的圖片, 不能獲取ws2,ws3等用戶的圖片,所以paint一定要取得ws的信任拿到密碼.
3.簡化模式(Implicit)
paint要得到access_token並且,不必知道ws的具體密碼.
paint會訪問qq空間某一api接口時,告知client_id, user_id, redirect_url,qq空間收到請求后將頁面跳轉到認證頁面,
然后瀏覽器跳轉至qq空間的認證頁面,用戶ws在此頁面輸入用戶名密碼,在qq空間認證成功后.
qq空間將瀏覽器跳轉到paint提前指定的redirect_url上,傳入access_token. 這時paint即可得到access_token.
注:
這里的access_token如何能被paint得到? 就是解析redirect_url的參數.
比如這樣 ,直接取url參數得到access_token為abcdefg.
http://my.redirect_url.com?access_token=abcedfg
在一些移動應用的程序內部實現時,即使redirect_url是一個錯誤的地址,也能解析到access_token.
因為應用內部會收到302跳轉的數據,只要從中解析到token后,不執行跳轉動作即可.
這個問題,困惑了我好久.經過朋友幫助才終於理解.
4.授權碼模式(Authorization Code)
授權碼模式與簡化模式的過程是一樣的.
不同之處在於,qq空間跳轉到paint的redirect_url時,不直接返回access_token,而是返回一個code.
paint需要再將code發到qq空間,請求對應的access_token.
為什么要多此一舉?
簡化模式適用於paint是移動客戶端應用的情況, 這個應用請求access_token后, 可直接獲取到access_token.並且這個access_token是在url參數后的.
也就是如果客戶端能顯示出網址,用戶就能看見access_token. 此時access_token是相對公開的不安全.
而授權碼模式適用於paint是移動客戶端應用,而且擁有自己的公網服務器, 那么它可以在請求到access_token時, 首先是公網服務器(通過redirect_url)得到code,
由公網服務器使用code請求access_token. 這時paint的公網服務器直接向qq空間請求照片,然后再將照片轉發到paint移動客戶端應用.
整個過程客戶端是沒有得到access_token的.相對來說更安全.
授權碼模式時序圖(引用自騰訊)
(user: 用戶ws App:第三方應用paint Auth_svr:認證服務器,qq空間)
四、總結
上面就是自己的淺見,本人實踐過程僅搭建了一個簡單的OAuth2.0服務器,用於其他合作伙伴訪問我們的api時進行權限認證.
是一個比較簡單的應用.
在學習理解OAuth2.0過程,參考了阮老師的文章.他的語言文字描述更准確透徹,且容易理解. 可以點擊此處查看.
另外,OAuth2.0官網上的教程一步一步搭建OAuth2.0服務器對我幫助也很大.
官網有好幾種實現方式,都是開源貢獻者的精華,我只詳細看了php的實現,就已經深深佩服.
一個看似簡單的功能,竟然能實現的非常靈活, 僅需要很少的改動就能完整實現上述的4種認證授權模式,並且還有本文沒有提到,但是標准中定義的很多其他細節.
五、參考資料:
0. 如何選擇OAuth2.0各種授權類型
https://github.com/thephpleague/OAuth2-server/wiki/Which-OAuth-2.0-grant-should-I-use%3F
1.OAuth1.0 OAuth2.0的實現原因及安全性問題, 是PPT內容。
2.關於OAuth2.0的規范詳細理解。
理解OAuth 2.0 作者: 阮一峰
http://www.ruanyifeng.com/blog/2014/05/OAuth_2_0.html
3.其他網站使用OAuth2.0授權認證的接口文檔
關於OAuth2.0的詳細介紹,請參考OAuth2.0協議標准。
騰訊 (這個有時序圖,講的比較清晰。當然要配合”理解OAuth 2.0”一起理解)
http://wiki.open.t.qq.com/index.php/OAuth2.0%E9%89%B4%E6%9D%83#.E8.8E.B7.E5.8F.96accesstoken.E7.9A.84.E4.B8.A4.E7.A7.8D.E6.96.B9.E5.BC.8F
人人網
http://wiki.dev.renren.com/wiki/Authentication
來往
http://open.laiwang.com/docs/authentication.html
微信認證的接口使用方法.
http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token
4.幫你深入理解OAuth2.0協議
http://blog.csdn.net/seccloud/article/details/8192707
OAuth協議實例化描述
下面我以實例化方式來幫助讀者理解授權碼類型的授權協議的運行過程。假設:
(1) Alice有一個有效的Google帳號;
(2) Facebook.com已經在Google Authorization Server上注冊了Client身份,已經獲得(client_id, client_secret),注意client_secret是Client與AS之間的一個共享密鑰。
(3) Alice想授權Facebook.com查看她的聯系人列表(https://www.google.com/m8/feeds)。
圖3展示了Alice、Facebook.com、Google資源服務器、以及Google OAuth授權服務器之間的協議運行過程。
