OAuth2 vs JWT,到底怎麼選?

文章轉載來源:www.jianshu.com/p/1f2d6e5126cb

| 背景

本文會詳細描述兩種通用的保證 API 安全性的方法:OAuth2 和 JSON Web Token (JWT)

假設:

| JWT 和 OAuth2 比較?

先來搞清楚 JWT 和 OAuth2 究竟是幹什麼的~

| JSON Web Token (JWT)

JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS). -RFC7519 https://tools.ietf.org/html/rfc7519

JWT 是一種安全標準。基本思路就是用戶提供用戶名和密碼給認證服務器,服務器驗證用戶提交信息信息的合法性;如果驗證成功,會產生並返回一個 Token(令牌),用戶可以使用這個 token 訪問服務器上受保護的資源。

一個 token 的例子:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

一個 token 包含三部分:

header.claims.signature

爲了安全的在 url 中使用,所有部分都 base64 URL-safe 進行編碼處理。

Header 頭部分頭部分簡單聲明瞭類型 (JWT) 以及產生簽名所使用的算法。

{  "alg" : "AES256",  "typ" : "JWT"}

Claims 聲明

聲明部分是整個 token 的核心,表示要發送的用戶詳細信息。有些情況下,我們很可能要在一個服務器上實現認證,然後訪問另一臺服務器上的資源;或者,通過單獨的接口來生成 token,token 被保存在應用程序客戶端(比如瀏覽器)使用。

一個簡單的聲明(claim)的例子:

{  "sub""1234567890",  "name""John Doe",  "admin": true}

Signature 簽名

簽名的目的是爲了保證上邊兩部分信息不被篡改。如果嘗試使用 Base64 對解碼後的 token 進行修改,簽名信息就會失效。一般使用一個私鑰(private key)通過特定算法對 Header 和 Claims 進行混淆產生簽名信息,所以只有原始的 token 才能與簽名信息匹配。   

這裏有一個重要的實現細節。只有獲取了私鑰的應用程序(比如服務器端應用)才能完全認證 token 包含聲明信息的合法性。所以,永遠不要把私鑰信息放在客戶端(比如瀏覽器)。

| OAuth2 是什麼?

相反,OAuth2 不是一個標準協議,而是一個安全的授權框架。它詳細描述了系統中不同角色、用戶、服務前端應用(比如 API),以及客戶端(比如網站或移動 App)之間怎麼實現相互認證。

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. -RFC6749 https://tools.ietf.org/html/rfc6749

這裏簡單說一下涉及到的基本概念。

Roles 角色

應用程序或者用戶都可以是下邊的任何一種角色:

Client Types 客戶端類型

這裏的客戶端主要指 API 的使用者。它可以是的類型:

Client Profile 客戶端描述

OAuth2 框架也指定了集中客戶端描述,用來表示應用程序的類型:

Authorization Grants 認證授權

認證授權代表資源擁有者授權給客戶端應用程序的一組權限,可以是下邊幾種形式:

OAuth2 框架需要下邊幾種終端:

從上邊這些應該可以看出,OAuth2 定義了一組相當複雜的規範。

使用 HTTPS 保護用戶密碼

在進一步討論 OAuth2 和 JWT 的實現之前,有必要說一下,兩種方案都需要 SSL 安全保護,也就是對要傳輸的數據進行加密編碼。   

安全地傳輸用戶提供的私密信息,在任何一個安全的系統裏都是必要的。否則任何人都可以通過侵入私人 wifi,在用戶登錄的時候竊取用戶的用戶名和密碼等信息。

一些重要的實施考慮

在做選擇之前,參考一下下邊提到的幾點。

時間投入

OAuth2 是一個安全框架,描述了在各種不同場景下,多個應用之間的授權問題。有海量的資料需要學習,要完全理解需要花費大量時間。甚至對於一些有經驗的開發工程師來說,也會需要大概一個月的時間來深入理解 OAuth2。這是個很大的時間投入。相反,JWT 是一個相對輕量級的概念。可能花一天時間深入學習一下標準規範,就可以很容易地開始具體實施。

出現錯誤的風險

OAuth2 不像 JWT 一樣是一個嚴格的標準協議,因此在實施過程中更容易出錯。儘管有很多現有的庫,但是每個庫的成熟度也不盡相同,同樣很容易引入各種錯誤。在常用的庫中也很容易發現一些安全漏洞。

當然,如果有相當成熟、強大的開發團隊來持續 OAuth2 實施和維護,可以一定程度上避免這些風險。

社交登錄的好處

在很多情況下, 使用用戶在大型社交網站的已有賬戶來認證會方便。

如果期望你的用戶可以直接使用 Facebook 或者 Gmail 之類的賬戶, 使用現有的庫會方便得多。

| 結論

做結論前,我們先來列舉一下  JWT 和 OAuth2 的主要使用場景。

JWT 使用場景

無狀態的分佈式 API

JWT 的主要優勢在於使用無狀態、可擴展的方式處理應用中的用戶會話。服務端可以通過內嵌的聲明信息,很容易地獲取用戶的會話信息,而不需要去訪問用戶或會話的數據庫。在一個分佈式的面向服務的框架中,這一點非常有用。   

但是,如果系統中需要使用黑名單實現長期有效的 token 刷新機制,這種無狀態的優勢就不明顯了。

優勢

限制

| 在作者看來兩種比較有必要使用 OAuth2 的場景:

外包認證服務器

上邊已經討論過,如果不介意 API 的使用依賴於外部的第三方認證提供者,你可以簡單地把認證工作留給認證服務商去做。也就是常見的,去認證服務商(比如 facebook)那裏註冊你的應用,然後設置需要訪問的用戶信息,比如電子郵箱、姓名等。當用戶訪問站點的註冊頁面時,會看到連接到第三方提供商的入口。用戶點擊以後被重定向到對應的認證服務商網站,獲得用戶的授權後就可以訪問到需要的信息,然後重定向回來。

優勢

大型企業解決方案

如果設計的 API 要被不同的 App 使用,並且每個 App 使用的方式也不一樣,使用 OAuth2 是個不錯的選擇。

考慮到工作量,可能需要單獨的團隊,針對各種應用開發完善、靈活的安全策略。當然需要的工作量也比較大!這一點,OAuth2 的作者也指出過:

To be clear, OAuth 2.0 at the hand of a developer with deep understanding of web security will likely result is a secure implementation. However, at the hands of most developers – as has been the experience from the past two years – 2.0 is likely to produce insecure implementations. hueniverse - OAuth 2.0 and the Road to Hell

優勢

參考:

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/lAz0DcydLChtAmWFgBuraA