天天看點

Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

一、什麼是鑒權?為什麼要鑒權

鑒權(authentication),也叫做認證,即驗證使用者是否擁有通路系統的權利。

HTTP本身是無狀态的請求,每次請求都是一次性的,并不會知道請求前後發生了什麼。但在很多情況情況下都需要維護狀态,最典型的就是使用者登入系統,并在系統中進行一系列操作

API接口直接暴露在網際網路上是存在安全風險的,如果不進行鑒權,就有可能被網上的不法分子惡意攻擊(如:爬蟲,惡意通路等),使得api資源被非法通路占用,正常使用者通路受阻。是以鑒權十分必要,隻有鑒權成功的請求才能請求服務,否則就被攔截

Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

二、Cookie/Session鑒權

為每個使用者頒發一個身份牌

為了識别使用者,可以為每個使用者設定一個“身份牌”,“身份牌”裡面可以存放使用者的資訊,每次請求的時候都帶上這個“身份牌”,這樣就可以用來識别使用者了。而這個“身份牌”就是我們經常提到的“cookie”

Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

Session會話的引入

随着web應用的告訴發展,越來越多的使用者資訊需要存儲,如果僅僅依靠Cookie字段存儲,會大大增加每次請問的負擔。

是以引入會話(session)的概念,使用一個會話ID(sessionID)映射到使用者的各種資訊上,每次請求隻需要在cookie攜帶上sessionID就可以解決cookie增長的問題

Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

為了更好的負載均衡與容災,後端伺服器一般使用分布式方式部署,一個使用者的Session資訊在單台伺服器上建立後需要同步給其餘的伺服器。是以Session映射采用Redis等緩存伺服器方式才能解決跨地域多機房問題

(為了負載均衡與容災,Redis叢集也需要使用多機房部署)

Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

局限

  • 依賴cookie,cookie可以被禁用,也可以被劫持篡改
  • 移動端中cookie和session機制不被支援,跨平台不好相容
  • 緩存伺服器的多機房資訊同步需要時間,如果服務某個機房出現問題,依然可能造成使用者Session短暫失敗

二、token授權之JWT

分散壓力

既然基于cookie的session鑒權存在上述問題,那麼能否改變一下思路,跳出以上的局限性。

Session會話機制的痛點在于,Session的使用者解析需要後端服務來維護邏輯,甚至還需要一個緩存伺服器來維護,這使得一次請求的鍊路變長,出現問題的機率也比較大

那幹脆讓用戶端來維護自己的使用者資訊就好了,這樣大量的使用者資訊就分散到各個使用者的裝置上,伺服器的壓力就會減少很多

客戶維護鑒權資訊的機制類似于http協定也是無狀态的,這也使得整個服務拓展性大大提升

用token代替session

  • 使用者第一次登入,伺服器驗證使用者,通過後生成一個token
  • 在第一次傳回時将token傳回給用戶端,用戶端存儲下來,下次請求時攜帶上該token
  • 之後隻要驗證token是否有效即可
  • 為了避免篡改,可以在token中使用加密算法生成簽名,加入token(私鑰儲存在伺服器上,是以簽名無法被破解)
    Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

JWT(JSON Web Token)token生成标準

JSON Web Token (JWT)是一個開放标準(RFC 7519),它定義了一種緊湊的、自包含的方式,用于作為JSON對象在各方之間安全地傳輸資訊。因為攜帶了數字簽名,是以該資訊可以被驗證和信任的

JWT由三部分資料組成,三部分由 點(.) 進行分割

  • Header(頭部)
  • Payload(負載)
  • Signature(簽名)

    Header.Payload.Signature

Header

Header 部分是一個 JSON 對象,描述 JWT 的中繼資料,例如:

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

alg屬性表示簽名的算法(algorithm),預設是 HMAC SHA256(寫成 HS256);typ屬性表示這個令牌(token)的類型(type),JWT 令牌統一寫為JWT

最後,将上面的 JSON 對象使用 Base64URL 算法轉成字元串

Payload

Payload 部分也是一個 JSON 對象,用來存放實際需要傳遞的資料。JWT 規定了7個官方字段,可以從中選擇使用

iss (issuer):簽發人
exp (expiration time):過期時間
sub (subject):主題
aud (audience):閱聽人
nbf (Not Before):生效時間
iat (Issued At):簽發時間
jti (JWT ID):編号
           

當然也可以自定義字段,不過由于這部分資料是明文傳送,是以不要在payload字段上存放任何私密資訊

Signature

Signature 部分是對前兩部分的簽名,防止資料篡改。

首先,需要指定一個密鑰(secret)。這個密鑰隻有伺服器才知道,不能洩露給使用者。然後使用 Header 裡面指定的簽名算法(預設是 HMAC SHA256),按照下面的公式産生簽名。

算出簽名以後,把 Header、Payload、Signature 三個部分拼成一個字元串,每個部分之間用"點"(.)分隔,就可以傳回給使用者

因為使用了簽名,是以即使洩露,也無法被篡改

局限

  • 伺服器不儲存Session資訊,在沒有特殊邏輯的情況下,無法在使用過程中廢止某個 token,也不能更改 token 的權限,一旦 JWT 簽發了,在到期之前就會始終有效
  • Token本身就是認證資訊,一旦洩露,任何人都可以獲得該令牌的所有權限。為了減少盜用,JWT 的有效期應該設定得比較短。對于一些比較重要的權限,使用時應該再次對使用者進行認證
  • 為了減少盜用,JWT 不應該使用 HTTP 協定明碼傳輸,要使用 HTTPS 協定傳輸

三、token授權之OAuth2.0

嚴格來講,OAuth2.0不算一種授權方式,而是一個安全的授權認證的架構。為系統中不同角色、使用者、服務前端應用(比如API),以及用戶端(比如網站或移動App)提供了一套互相認證的架構

是以一般而言,在OAuth2.0中存在三種角色:服務提供方,使用者,第三方服務 ;使用者授權第三方服務使用自身的某些權限,去通路服務提供方的資源(比如用qq賬戶登入微網誌)

OAuth2.0分為兩步,擷取Authorization以及擷取Token

擷取Authorization

  • 使用者在授權界面,選擇需要授權的權限點,登入确定授權
  • 授權後回調第三方服務的回調位址
  • 通過回調位址,發送Authorization(可以看做是驗證碼,有效期不長)給第三方服務

擷取Token并維護Token有效性

  • 通過上面拿到的Authorization調用服務提供方的接口擷取token
  • token由access token與refresh token兩個token組成,access token有效性比refresh token短
  • 通路服務提供方接口需要使用access token,而當access token快過期的時候就需要用refresh token請求token重新整理接口,擷取新的token
    Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權
    OAuth 2.0 rfc文檔:https://www.rfc-editor.org/rfc/rfc6749

OAuth2.0提供了4種認證方式,上面是最為複雜的一種,授權碼模式,其餘3種授權方式如下

簡化模式

不通過第三方應用程式的伺服器,直接在浏覽器中向認證伺服器申請令牌,跳過了"授權碼"這個步驟。所有步驟在浏覽器中完成,令牌對通路者是可見的,且用戶端不需要認證

Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

(A)用戶端将使用者導向認證伺服器。

(B)使用者決定是否給于用戶端授權。

(C)假設使用者給予授權,認證伺服器将使用者導向用戶端指定的"重定向URI",并在URI的Hash部分包含了通路令牌。

(D)浏覽器向資源伺服器送出請求,其中不包括上一步收到的Hash值。

(E)資源伺服器傳回一個網頁,其中包含的代碼可以擷取Hash值中的令牌。

(F)浏覽器執行上一步獲得的腳本,提取出令牌。

(G)浏覽器将令牌發給用戶端。

密碼模式

使用者向用戶端提供自己的使用者名和密碼。用戶端使用這些資訊,向"服務商提供商"索要授權。

在這種模式中,使用者必須把自己的密碼給用戶端,但是用戶端不得儲存密碼。這通常用在使用者對用戶端高度信任的情況下,比如用戶端是作業系統的一部分,或者由一個著名公司出品。而認證伺服器隻有在其他授權模式無法執行的情況下,才能考慮使用這種模式

Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

(A)使用者向用戶端提供使用者名和密碼。

(B)用戶端将使用者名和密碼發給認證伺服器,向後者請求令牌。

(C)認證伺服器确認無誤後,向用戶端提供通路令牌。

用戶端模式

指用戶端以自己的名義,而不是以使用者的名義,向"服務提供商"進行認證

Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

(A)用戶端向認證伺服器進行身份認證,并要求一個通路令牌。

(B)認證伺服器确認無誤後,向用戶端提供通路令牌。

優點

  • 更安全,用戶端不接觸使用者密碼
  • 資源伺服器可以和授權伺服器解耦
  • 适用多種用戶端架構場景

缺點

  • 協定架構太寬泛,每個服務又都自己的實作,相容性和互操作性比較差
  • 用戶端需要維護token有效性,維護定時重新整理token任務

四、ak/sk認證鑒權

  • 服務提供方需要給每個使用者配置設定一對 Access Key Id(AK) / Secret Access Key(SK)
  • 雙方約定同樣的加密算法,利用 時間戳,sk,nonce(一個随機值,為了避免請求重放),參數等資訊作為計算因子,算出sign簽名
  • 使用者在調用api時,需要提供自己的身份認證(AK),時間戳、nonce以及加密好的sign簽名
  • 服務提供方驗證簽名是否過期,驗證nonce是否唯一,并利用同樣的算法算出sign,與傳入sign進行比對,如果一緻則通過認證
    Web API接口鑒權方式一、什麼是鑒權?為什麼要鑒權二、Cookie/Session鑒權二、token授權之JWT三、token授權之OAuth2.0四、ak/sk認證鑒權

優點

  • 安全性高,在秘鑰與算法不洩露情況下,簽名無法破解
  • 有過期時間,可以避免簽名長期有效的情況
  • 有防止重放機制,即使簽名被捕獲,也無法再次利用相同的簽名進行請求

缺點

  • 對于服務調用方與被調用方都需要一定的編碼要求
  • 每次請求都需要重新計算簽名,不那麼輕量
  • 服務提供方需要維護ak/sk關系,并且需要維護nonce是否唯一邏輯

繼續閱讀