OAuth授權|看這篇就夠了

小忽悠發表於2018-09-09

背景

上一篇我們介紹了單點登入(SSO),它能夠實現多個系統的統一認證。今天我們來談一談近幾年來非常流行的,大名鼎鼎的OAuth。它也能完成統一認證,而且還能做更多的事情。至於OAuth與SSO的區別,將在文章最後總結。

image1

如上圖所示,使用者通過瀏覽器(Browser)訪問app1,他想用微信的賬號直接登入,這樣就免去了在app1系統的註冊流程。這樣的流程完全符合單點登入(SSO),但我們今天要看看OAuth是怎麼做的。

具體流程

image2

流程比單點登入(SSO)複雜了很多,但是它比SSO更強大。接下來我們好好捋一捋這個流程:

  1. 使用者訪問app1系統,app1返回登入頁,讓使用者登入。
  2. 使用者點選微信登入,這裡的微信就是OAuth Server,跳轉到微信登入頁,帶上引數appid和回撥地址(backUrl)。關於appid我們要詳細
    說一下,我們在與OAuth Server做對接的時候,先要在OAuth Server上註冊自己的系統(app1),需要填寫應用的名稱、回撥地址等, OAuth Server會生成appid和appSecret,這兩個變數是非常關鍵的。
  3. 微信後臺(OAuth Server)根據appid查詢到app1的註冊資訊,校驗引數backUrl和註冊的回撥地址是否一致(這裡可以只校驗域名或者一級域名,具體要看OAuth Server怎麼設計),如果校驗不通過則返回錯誤,校驗成功則返回授權頁。
  4. 微信彈出授權頁,如果微信沒有登入則彈出登入並授權頁。這個過程是微信詢問使用者,是否同意app1系統訪問微信的資源。使用者授權後, 微信後臺(OAuth Server)會生成這個使用者對應的code,並通過app1的backUrl返回app1系統。
  5. app1系統拿到code後,再帶上appid和appSecret從後臺訪問微信後臺(OAuth Server),換取使用者的token。
  6. app1拿到token後,再去微信後臺(OAuth Server)獲取使用者的資訊。
  7. app1設定session為登入狀態,並將使用者資訊(暱稱、頭像等)返回給Browser。

到這裡,OAuth的授權流程就結束了。有的同學可能很快就會問到:使用者授權後,為什麼不直接返回token,而是要用code換取token?這是因為如果直接返回token,token會先到瀏覽器(Browser),然後再到app1系統,到了瀏覽器,這個token就是不安全的了,有可能被竊取,token被竊取後,微信後臺(OAuth Server)中,這個使用者的資訊就不安全了。然而在用code換取token時,是帶上了appid和appSecret的,微信後臺(OAuth Server)可以判斷appid和appSecret的合法性,確認無誤後,再將token返回給app1。這裡是直接返回app1,沒有經過瀏覽器,token是安全的。

靜默登入

上面的流程是使用者先訪問app1,點選微信登入後,跳到微信。如果我們先開啟了微信,在微信裡邊再開啟app1,這個流程就好像我們在
微信裡開啟了京東,這裡微信就是OAuth Server,京東就是app1。在這個流程中,我們可以省略掉詢問使用者是否授權的過程,也就是在微信裡開啟京東(app1)的時候,京東(app1)帶著appid和backUrl訪問微信(OAuth Server),微信(OAuth Server)驗證appid和backUrl,並且微信(OAuth Server)已經是登入的,這裡並沒有詢問使用者是否授權京東訪問自己在微信的資源,直接將code返回給了京東。從而使京東登入,並且在京東里顯示的使用者在微信中的暱稱和頭像等資訊。

使用靜默登入一般都是你的系統做的比較牛了,被資源方看中了,要把你的系統嵌入到資源方去。比如:微信中嵌入了京東。

上面的例子中,我們只做了獲取使用者資訊,其實還可以開放很多資訊,例如:使用者的賬戶餘額等。要開放哪些資源就看OAuth Server的了。
這也就是我們常說的open api。要做open api,上面的OAuth流程是必不可少的。

與單點登入(SSO)的對比

單點登入(SSO)是保障客戶端(app1)的使用者資源的安全 。

OAuth則是保障服務端(OAuth)的使用者資源的安全 。


單點登入(SSO)的客戶端(app1)要獲取的最終資訊是,這個使用者到底有沒有許可權訪問我(app1)的資源。

OAuth獲取的最終資訊是,我(OAuth Server)的使用者的資源到底能不能讓你(app1)訪問。


單點登入(SSO),資源都在客戶端(app1)這邊,不在SSO Server那一方。 使用者在給SSO Server提供了使用者名稱密碼後,作為客戶端app1並不知道這件事。 隨便給客戶端(app1)個ST,那麼客戶端(app1)是不能確定這個ST是否有效,所以要拿著這個ST去SSO Server再問一下,這個ST是否有效,是有效的我(app1)才能讓這個使用者訪問。

OAuth認證,資源都在OAuth Server那一方,客戶端(app1)想獲取OAuth Server的使用者資源。 所以在最安全的模式下,使用者授權之後,
服務端(OAuth Server)並不能通過重定向將token發給客戶端(app1),因為這個token有可能被黑客截獲,如果黑客截獲了這個token,那麼使用者的資源(OAuth Server)也就暴露在這個黑客之下了。 於是OAuth Server通過重定向傳送了一個認證code給客戶端(app1),客戶端(app1)在後臺,通過https的方式,用這個code,以及客戶端和服務端預先商量好的密碼(appid和appSecret),才能獲取到token,這個過程是非常安全的。 如果黑客截獲了code,他沒有那串預先商量好的密碼(appid和appSecret),他也是無法獲取token的。這樣OAuth就能保證請求資源這件事,是使用者同意的,客戶端(app1)也是被認可的,可以放心的把資源發給這個客戶端(app1)了。

總結:所以單點登入(SSO)和OAuth在流程上的最大區別就是,通過ST或者code去認證的時候,需不需要預先商量好的密碼(appid和appSecret)。

總結

OAuth和SSO都可以做統一認證登入,但是OAuth的流程比SSO複雜。SSO只能做使用者的認證登入,OAuth不僅能做使用者的認證登入,開可以做open api開放更多的使用者資源。


相關文章