系統設計學習筆記 - 搞懂 OAuth(開放授權) 與 SSO(單點登錄)
Intro
程式開發的過程中,卡關滿久的就是 OAuth 驗證,一直沒有真正搞懂背後的運作原理,也還沒試著實作它。最近感覺時候到了,就認真讀點書,把相關知識補起來,順便了解一下 SSO 跟 OAuth 的差別。
最基本的登入
一個提供給用戶的服務,可以想見一定具備兩大塊模組:
- 會員登入管理:包含身分驗證、帳號密碼等等
- 會員數據管理:依服務性質會有所不同,電商可能有購物車,部落格可能有文章資料等等
那麼,為了實現會員登入管理,你的直覺想法是什麼呢?
很簡單嘛!就是開一張 table,把會員的 account
(也許是一組 4~8 字符長度的英數字)和 password
(很認真地用了 regex 限制必須包含大小寫、至少 6~8 位字符、必須包含至少一個特殊符號、甚至不可以包含跟帳號有重疊的字段)存起來,當會員要登入的時候,開一支 API 把 account
password
送到後端做驗證是否通過,這不就結了嗎?
SOCKS,這確實是最基本的登入實作。
備註:SOCKS 單獨拆開來唸就會變成西班牙文
但是換個角度想想,假如今天你是使用者呢?
每想要使用一個服務,就要建一組帳號密碼,不同網站也許基於資安考量,每幾個月會要求變更一次密碼,是很貼心沒錯,但要保管的密碼不斷積累,到後來只要看到需要用帳號密碼註冊的網站就索性關閉,是你的話,你能保證不會有這個念頭嗎?
因此我們需要(對用戶來說)更方便的登入方式。
OAuth
解決了什麼問題?
Line、Google、Microsoft 這些具有規模的服務,本身已有龐大的會員資料及高安全性的資料保護,用戶們把資料儲存在這些服務中較安心,也省去每要使用一個網站的服務就需要註冊一組新的帳號密碼的麻煩。在這些前提下,這些巨頭提供了自己的身分驗證服務,讓小網站能夠將自己的會員與巨頭提供的會員帳號資料綁定,等於他們幫你驗證了這位用戶是他們會員中的哪一位,身分得到了驗證,還得到與巨頭的關聯。
為了統一各家巨頭提供的串接服務的標準,OAuth
標準因應而生。
OAuth 2.0 是什麼?
OAuth 2.0 是一個開放授權協議,讓用戶能安全地授予第三方服務權限,在不用暴露密碼的情況下能夠存取他們同意被存取的某些資源。OAuth 2.0 引入了授權層,將用戶與第三方應用分開來,用戶可以指定授權的權限範圍及效期,第三方服務通過獲取訪問令牌來存取用戶的資源,而不是直接使用用戶的密碼,提高了安全性。OAuth 2.0 已經是一種行業標準,廣泛應用在雲服務、社交媒體等領域。
它定義了四種授權模式:
- 授權碼模式(Authorization Code Grant)
- 適用有後端服務的應用
- 客戶端將用戶導向認證服務器進行身分驗證和授權
- 認證服務器驗證身分及授權後,回覆授權碼
- 客戶端使用授權碼向認證服務器請求訪問令牌
- 簡化模式(Implicit Grant)
- 適用純前端應用
- 客戶端將用戶導向認證服務器進行身分驗證和授權
- 認證服務器驗證身分及授權後,直接回覆訪問令牌
- 密碼模式(Resource Owner Password Credentials Grant)
- 適用高度可信的應用,如企業內部應用
- 用戶直接向客戶端提供用戶名及密碼
- 客戶端使用用戶憑證向認證服務器請求訪問令牌
- 客戶端模式(Client Credentials Grant)
- 適用於機器對機器的認證
- 客戶端使用自己的身分向認證服務器請求訪問令牌
- 此模式不涉及用戶授權
授權碼模式 OAuth 登入流程
既然有這麼多巨頭服務提供身分認證,那我們的網站為了讓用戶有更良好的體驗,勢必就要串接這些身分認證功能,讓用戶可以透過 OAuth 驗證他們的帳號,進而連結我們自己網站上的會員資料。
假設今天要實作 Google Login,OAuth 服務提供商就是 Google,而流程大致上如下:
- 用戶在你的網站上點擊「透過 Google 登入」
- 你的服務(對 Google 而言你就是客戶端,所以需要有 clientId)請求授權
- 將用戶轉導到 Google 的身分驗證頁面
- 用戶在頁面上進行身分驗證
- Google 回覆授權碼
code
- 轉導回你的服務
- 你的服務拿著授權碼向 Google 驗證這位使用者的授權
- Google 回覆一個訪問令牌
access_token
,這個令牌包含使用者同意你存取的資源範圍(個人資料、Google drive...等等)
基本上做完上面幾個流程,你就能確定 Google 有驗證這位用戶的身分,也就能通過你的服務的 Google Login 了。
除非你的服務有進一步的功能,需要操作用戶的其他受保護的資源,就是下面的情況。
OAuth 進階應用
- 第三方應用服務訪問用戶資源 舉例來說,假如你開發的是一個更美觀的 Google Drive 操作介面,就需要取得用戶的「Google Drive 存取權限」,這就需要拿著令牌去操作 Google Drive 資源了。
- API 授權 你的服務要訪問用戶的某個資源時(例如社交媒體、支付服務),OAuth 提供一個安全的交互方式,讓服務有權限訪問這些資源,無須用戶提供密碼。
SSO(單點登錄)又是什麼?
假設你的公司有幾個服務:
- 員工基本資料管理服務
- 員工出勤管理服務
- 員工績效管理服務
- 各部門自己的服務
而你希望員工在這些服務之間,只需要登入一次,在 token 有效期間內就不需要重新登入,那麼就需要 SSO(單點登錄)。
你會有一個服務專門管理員工的登入狀態,並保管他的 access_token
與核發的內部訪問令牌(看你是用什麼做,通常就 jwt
)。一但員工要使用某個服務,該服務就會來問這個登入狀態管理服務「令牌有效否?」,進而允許員工做出一些操作,也省得員工在這些服務之間,有幾個服務就要創幾個帳號,各帳號之間資料不同步,那會瘋掉。
簡單說,SSO 就是把登入狀態抽出來單獨管理,並允許其他服務來使用它,概念上有點類似自己做的小型身分認證服務。
SSO vs OAuth
目的
機制 | 目的 |
---|---|
SSO | 單點登錄的主要目的是讓用戶在不同系統中,只需要登錄一次就可以訪問,不需要每個系統都註冊一遍,免去管理繁雜帳號的麻煩。通常用於同一組織內的多個應用之間的身分驗證。 |
OAuth | 主要目的是得到授權,允許第三方應用代理用戶存取某些資源,例如使用 Google 帳戶登錄第三方應用。 |
運作方式
機制 | 運作方式 |
---|---|
SSO | 用戶首次登錄後,身分驗證服務會生成一個令牌(token),該令牌可以在多個應用之間共享,用戶在訪問其他應用時,這些應用只需要驗證這個令牌的有效性即可。 |
OAuth | 用戶授權第三方應用訪問其資源時,會生成一個訪問令牌(access token),該令牌用於授權第三方應用訪問用戶的數據,這通常涉及用戶及授權服務之間的交互。 |
情境
機制 | 情境 |
---|---|
SSO | 適用於需要在同一組織內部的多個應用服務之間共享登錄狀態的場景,例如企業內部系統。 |
OAuth | 適用於需要授權第三方應用訪問用戶數據的場景,例如社交媒體登錄,API 訪問等。 |
小結
- SSO 主要解決用戶在多個應用之間的登錄問題,提供無縫的用戶體驗。
- OAuth 主要解決授權問題,允許用戶授權第三方應用訪問其資源,而不需要提供密碼。
兩者可以同時使用,例如在同個企業應用中,使用 SSO 來管理用戶的登錄狀態,同時使用 OAuth 來授權第三方應用訪問企業資源。
最終方法還是要取決於需求。