理解 OAuth 2.0 協議的原理

Web安全的問題其實頗有意思,這些在互聯網上使用的安全協議看似複雜,其實在現實生活中都有相似的準則被人們理所固然地普遍使用。好比這裏要講的受權,這是個全部人都很熟悉的概念。例如你要給張三1000元現金,你手裏沒現金,就想讓張三直接去你銀行帳戶裏取,那你會怎麼作呢?你能夠這樣:html

  • 把你的銀行帳號密碼告訴張三讓他去銀行取錢

但顯然傻瓜纔會這樣幹,正確的作法是這樣:前端

  • 開一張1000元的支票給張三去銀行支取

這張支票就是受權的憑證,表明你受權張三從你的銀行帳戶裏提取1000元。這樣的事情發生在互聯網上,那就是一個第三方App,想要獲取你在某一網站上的一些私有信息(例如郵箱,名字,照片),須要獲得你的受權。這個受權的過程原理和上面的支票相似,固然在具體實現上須要更復雜更嚴密的步驟,這就是OAuth協議作的事情。瀏覽器

有一個很常見的場景,就是在不少App上,每每可使用你另外一個平臺上(微信,QQ等)的帳號註冊登陸,例如簡書:安全

圖片描述

你能夠點擊QQ登陸,它會給你轉到QQ受權登陸簡書的界面,從這裏開始就進入了OAuth 2.0協議的執行流程了。服務器

OAuth 2.0 協議 - 受權碼模式

網上介紹OAuth 2.0協議的文章也挺多的,因此咱們直奔主題,結合上面的例子,講講使用最廣,最嚴密的一種實現方式 - 受權碼模式微信

圖片描述

這裏直接貼一張 RFC 6749 裏的圖,是整個受權碼實現過程的流程圖。這裏有幾個名詞須要解釋一下:網站

  • Resource Owner,就是資源的主人。
  • User Agent,通常就是瀏覽器。
  • Client,這裏是指第三方App,例如簡書,注意這裏是指它的後臺而不是前端。
  • Authorization Server,受權服務器,例如QQ的受權服務器,它管理用戶QQ信息的受權。

上面圖中的 ABCDE 五個步驟:spa

(A)Client(即第三方App)將用戶導向Authorization Server地址,而且提供一個重定向URL。
(B)受權頁面詢問用戶,用戶贊成受權。
(C)Authorization Server產生一個受權碼,而且將用戶導向(A)中的重定向URL,帶上受權碼, 
    做爲URL的參數。
(D)這個重定向URL其實是Client域名下的一個地址,因而這個請求發送到了Client後臺,它使用
    受權碼向受權服務器申請一個token。
(E)Client獲得token,這個token就是一個令牌,能夠用來獲取用戶受權的資源。

咋一看彷佛仍是難以理解它的具體流程和原理,因此咱們仍是直接看上面的例子。3d

步驟(A)

在簡書的登陸界面,點擊QQ圖標,就會被導入到QQ登陸簡書的受權界面,即進入步驟(A),注意這是一個QQ域名下的頁面,如今暫時和簡書沒有關係了,對話只發生在用戶和QQ之間,咱們來看這個頁面的Http請求:code

URI:
https://graph.qq.com/oauth2.0/show?

參數:
which=Login
display=pc
client_id=100410602
redirect_uri=https://www.jianshu.com/users/auth/qq_connect/callback
response_type=code

這裏最重要的參數是:

  • client_id,表明了簡書,是它向QQ受權服務器申請的惟一ID。
  • redirect_uri,這是簡書域名下的一個地址,等一下子用戶贊成受權後,QQ會從新將瀏覽器導向這個地址。
  • 有時還會帶一個參數scope,這表示受權的範圍,好比用戶名字,qq號,好友列表之類的。

因此這個頁面其實是簡書將用戶導到了QQ,讓QQ和用戶達成協議,贊成受權給簡書。QQ將要求用戶登陸本身的QQ帳號,驗明身份,並向用戶徵求相應QQ信息的受權給簡書。在這裏沒有scope參數,而是QQ讓用戶在頁面上選擇相應的受權範圍,這實際上是同樣的。

圖片描述

步驟(B)

用戶在QQ的受權頁面上用QQ帳號登陸,而且選擇贊成受權給簡書相應QQ信息。

步驟(C)

用戶點擊贊成受權後,QQ將會生成一個受權碼(Authorization Code),而且將用戶導回以前(A)中的redirect_uri,它是這樣的:

URI:
https://www.jianshu.com/users/auth/qq_connect/callback?

附上受權碼:
code=1EE50EE39E4260EBCFA4892F72F84953

受權碼實際上就是用戶贊成受權的憑證,這個憑證將隨着這個URL發回給簡書。

步驟(D)

如今又回到了簡書的控制範圍,上面的URL由用戶瀏覽器發到簡書後,如今開始是簡書後臺的工做了。簡書將使用受權碼,向QQ申請一個token令牌,這個請求是發生在簡書後臺和QQ之間的,具體長什麼樣咱們固然不得而知,但它至少要包含如下信息:

  • 簡書的client_id
  • 和這個client_id對應的secret,這也是簡書在向QQ申請client_id時獲得的,由簡書保存,簡書用它向QQ服務器證實,這是我本人。
  • 受權碼

步驟(E)

QQ服務器驗證以上信息,向簡書發送token,簡書後面能夠用這個token獲取用戶的相應信息。

以後的工做就徹底由簡書決定了,一般的作法是它獲取了用戶QQ信息,而後作一系列處理,好比用用戶的qq號產生一個簡書帳號(或查找已經關聯該qq號的簡書帳號),實現登陸,再將用戶302重定向到簡書的主頁面。

原理分析

上面五個步驟,你來我往彷佛很複雜,咱們整理一下實際上就是兩個部分:

  1. (A)(B)(C)三步發生在用戶和QQ之間,固然是由簡書發起的。簡書要求QQ向用戶徵求受權,因而QQ和用戶開始對話,贊成受權,以受權碼爲憑證,這個受權碼包含的內容是:「用戶xx贊成向簡書提供QQ信息」。就相似於用戶在銀行開出一張支票,支票上寫着「用戶xx贊成向張三支付100元」。
  2. 而後(D)(E)兩步,轉到了簡書後臺和QQ之間,QQ重定向用戶瀏覽器到簡書以前提供的URL,附上那個受權碼,相似於你拿到了支票,將支票轉發給了張三。而後簡書拿着這個受權碼,加上能證實本身就是簡書的相關證件,也就是簡書的client_id和secret,向QQ換取一個token令牌,後面就能用這個token向QQ取得用戶受權的相關信息。

能夠看到這裏的邏輯是徹底符合咱們的生活常識的,正好對應咱們向張三開支票取錢的過程,只是步驟上更復雜更嚴密,由於互聯網的世界有更多風險因素須要考慮。有個問題你們常常會問到:

  • 爲何要分紅兩步,先拿受權碼,再換取token?若是對比支票的例子,自始至終支票只有一張,憑票便可兌錢。可是OAuth 2.0協議卻拆分紅了兩步,嚴格來說受權碼其實不是真正的支票,只是支票受權書,要獲取真正的支票token,須要簡書親自去向QQ索取。這是由於ABC三步發生在用戶和QQ服務器之間,這個對話信道是不可信任的,可能用戶的瀏覽器已被劫持。因此在這個信道上不能發送真正的token,不然token一旦泄露就失去全部安全性了,而只能發送一個受權碼做爲憑證,這個受權碼是和簡書綁定的。簡書拿到這個憑證以後,再帶上本身的身份證client_id和secret,才能向QQ換取真正的token支票。其餘人即便竊取了受權碼,但由於他們提供不了簡書的secret,QQ也會拒絕授予token。簡書和QQ之間的對話是發生在後臺的,能夠認爲這個信道的安全是有保障的。

後記

寫這篇是由於看到前一陣Facebook的數據泄漏事件,不過從來龍去脈來看FB彷佛也是被坑了一把,真正的始做俑者是那個叫Cambridge Analytica的公司,它獲取FB的用戶信息而且分析它們的喜愛性格,來有針對性地向他們推送帶有政治傾向的廣告和宣傳信息來影響選舉。聽說它爲了收集用戶數據,還在FB的遊戲平臺上發佈小遊戲。這種第三方App在用戶玩以前,每每會告知用戶將收集您的Facebook信息balabala,通常人經常看也不看就點贊成了:

圖片描述

這樣的霸王條款其實咱們已經很習慣了,一個第三方的App,想要獲取你在某些網站上的我的信息,就要用到Oauth協議,實現這種細粒度的受權。有些小遊戲他要求的受權範圍就很廣,包括獲取用戶在FB上全部的Post和點贊信息之類的,這其實就比較危險了,由於他能夠分析你的心理性格。還有些要求獲取好友列表的,這也值得警戒,由於那些數據收集的公司就是這樣由點到面相似爬蟲同樣獲取大量FB用戶的。FB的事情也是在提醒咱們,之後看到這樣的提示信息須要好好考慮一下,由於一旦點了贊成,就至關於你把「支票」開出去了。

相關文章
相關標籤/搜索