天天看點

OAuth2 vs JWT,到底怎麼選?

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

假設:

你已經或者正在實作API;

你正在考慮選擇一個合适的方法保證API的安全性;

JWT和OAuth2比較?

要比較JWT和OAuth2?首先要明白一點就是,這兩個根本沒有可比性,是兩個完全不同的東西。

JWT是一種認證協定

JWT提供了一種用于釋出接入令牌(Access Token),并對釋出的簽名接入令牌進行驗證的方法。令牌(Token)本身包含了一系列聲明,應用程式可以根據這些聲明限制使用者對資源的通路。      

Auth2是一種授權架構

另一方面,OAuth2是一種授權架構,提供了一套詳細的授權機制(指導)。使用者或應用可以通過公開的或私有的設定,授權第三方應用通路特定資源。既然JWT和OAuth2沒有可比性,為什麼還要把這兩個放在一起說呢?實際中确實會有很多人拿JWT和OAuth2作比較。标題裡把這兩個放在一起,确實有誤導的意思。很多情況下,在讨論OAuth2的實作時,會把JSON Web Token作為一種認證機制使用。這也是為什麼他們會經常一起出現。      

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

JSON Web Token (JWT)

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簽名

簽名的目的是為了保證上邊兩部分資訊不被篡改。如果嘗試使用Bas64對解碼後的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架構也指定了集中用戶端描述,用來表示應用程式的類型:

Web應用

使用者代理

原聲應用

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

授權碼

隐式授權

資源擁有者密碼證書

用戶端證書

Endpoints終端

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

認證終端

Token終端

重定向終端

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

使用HTTPS保護使用者密碼

在進一步讨論OAuth2和JWT的實作之前,有必要說一下,兩種方案都需要SSL安全保護,也就是對要傳輸的資料進行加密編碼。 安全地傳輸使用者提供的私密資訊,在任何一個安全的系統裡都是必要的。否則任何人都可以通過侵入私人wifi,在使用者登入的時候竊取使用者的使用者名和密碼等資訊。

一些重要的實施考慮 在做選擇之前,參考一下下邊提到的幾點。

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

出現錯誤的風險 OAuth2不像JWT一樣是一個嚴格的标準協定,是以在實施過程中更容易出錯。盡管有很多現有的庫,但是每個庫的成熟度也不盡相同,同樣很容易引入各種錯誤。在常用的庫中也很容易發現一些安全漏洞。 當然,如果有相當成熟、強大的開發團隊來持續OAuth2實施和維護,可以一定成都上避免這些風險。

社交登入的好處 在很多情況下,使用使用者在大型社交網站的已有賬戶來認證會友善。 如果期望你的使用者可以直接使用Facebook或者Gmail之類的賬戶,使用現有的庫會友善得多。

結論

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

JWT使用場景

無狀态的分布式API

JWT的主要優勢在于使用無狀态、可擴充的方式處理應用中的使用者會話。服務端可以通過内嵌的聲明資訊,很容易地擷取使用者的會話資訊,而不需要去通路使用者或會話的資料庫。在一個分布式的面向服務的架構中,這一點非常有用。 但是,如果系統中需要使用黑名單實作長期有效的token重新整理機制,這種無狀态的優勢就不明顯了。

優勢

快速開發

不需要cookie

JSON在移動端的廣泛應用

不依賴于社交登入

相對簡單的概念了解

限制

Token有長度限制

Token不能撤銷

需要token有失效時間限制(exp)

OAuth2使用場景

在作者看來兩種比較有必要使用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

靈活的實作方式

可以和JWT同時使用

可針對不同應用擴充

進一步

http://jwt.io

- JWT官方網站,也可以檢視到使用不同語言實作的庫的狀态。

http://oauth.net/2/

OAuth2官方網站, 也也可以檢視到使用不同語言實作的庫的狀态。

OAuth 2 tutorials - Useful overview of how OAuth 2 works

Oauth2 Spec issues Eran Hammer’s (推進OAuth标準的作者) views on what went wrong with the OAuth 2 spec process. Whatever your own opinion, good to get some framing by someone who understand’s key aspects of what make a security standard successful.

Thoery and implemnetation: with Laravel and Angular Really informative guide to JWT in theory and in practice for Laravel and Angular.