沐鳴登錄網站_JSON Web 令牌(JWT)是如何保護 API 的?

你可以已經聽說過 jsON Web Token (JWT) 是目前用於保護 API 的最新技術。

與大多數安全主題一樣,如果你打算使用它,那很有必要去了解它的工作原理(一定程度上)。問題在於,對 JWT 的大多數解釋都是技術性的,這一點讓人很頭疼。

讓我們看下,我能否解釋清楚 JWT 是如何在不引起你的注意下保護您的 API !

API 驗證

某些 API 資源需要限制訪問 。例如,我們不希望一個用戶能夠更改另一個用戶的密碼。

這就是為什麼我們保護某些資源,使用戶在允許訪問之前提供他的 ID 和密碼——換句話說,我們對它們進行身份驗證。

保護HTTP API的困難在於請求是 無狀態的 —— API 無法知道是否有兩個請求來自同一用戶。

那麼,為什麼不要求用戶在每次調用 API 時提供其 ID 和密碼呢?僅因為那將是可怕的用戶體驗。

jsON Web Token

我們需要的是一種允許用戶僅提供一次其憑證,隨後在後續請求中由服務器以另一種方式標識的方式。

為此設計了幾種系統,當前的最新標準是 JSON Web Token。

這是一篇 關於該主題的精彩文章 ,它很好地比喻了 JSON Web Token 的工作方式:

想象一下你要入住酒店,而不是一個 API 。「Token」是塑料酒店安全卡,可用於進入你的房間和使用酒店設施,但不能進入任何其他人的房間。

當你退房的時候,你交回卡片。這類似於註銷。

Token 的結構

通常, JSON Web Token 是通過 HTTP 請求頭髮送的。類似如下:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U

實際上, Token 部分是「Authorization: Bearer」之後的部分,僅是 HTTP 頭信息。

在你斷定這是難以理解的胡言亂語前,有幾件事你很容易注意到。

首先,Token是由三個不同的字符串組成,以句點分隔。這三個部分是 Base64 編碼 后的內容,並且分別對應 Header , Payload 以及 Signature

// Header eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

// Payload eyJzdWIiOiIxMjM0NTY3ODkwIn0

// Signature dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U

注意: Base64 是一種轉換字符串的方法,以確保在跨網絡傳輸期間不會被弄亂。這不是一種加密方式,任何人都可以 
輕鬆解碼
 以查看原始數據

我們可以對這些字符串進行解碼,以更好地了解JWT的結構。

Header

以下是 Token 中的已解碼 Header 部分。Header 是 Token 的元信息。它並沒有告訴我們很多幫助你建立基本理解的知識,因此我們不會對此進行任何詳細介紹。

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

Payload

Payload 能引起更多的關注。如果你想, Payload 可以包含任何數據,但是如果 Token 的目的是 API 訪問身份驗證,則可以僅包含用戶 ID 。

{ 
  "userId": "1234567890" 
}

請注意, Payload 不安全 。 任何人都可以解碼 Token ,並確切了解 Payload 中的內容。因此,我們通常會包含一個 ID ,而不是諸如用戶电子郵件之類的敏感識別信息。

即使 Payload 是在 API 上識別用戶所需要的全部,它也不能提供身份驗證的方法。如果其中包含所有內容,則有人可以輕鬆找到你的用戶 ID 並偽造 Token 。

因此,這使我們進入了 Signature 部分,這是認證 Token 的關鍵部分。

哈希算法

在解釋簽名如何工作之前,我們需要定義什麼是哈希算法。

首先,它是一個將字符串轉換為稱為 Hash 的新字符串的函數。例如,假設我們要對字符串「Hello, world」進行哈希處理。這是我們使用 SHA256 哈希算法得到的輸出:

4ae7c3b6ac0beff671efa8cf57386151c06e58ca53a78d83f36107316cec125f

哈希的最重要屬性是 你無法通過哈希算法來查看 Hash 的原始文本 。

有許多不同類型的哈希算法,但 SHA256 通常與 JWT 一起使用。

換句話說,我們不能根據上面的散列值算出原始字符串是 Hello,world。哈希非常複雜,以至於無法猜測原始字符串。

JWT 簽名

回到 JWT 結構,來看一下令牌的第三部分,簽名。實際上需要計算:

HMACSHA256( 
  base64UrlEncode(header) + "." + base64UrlEncode(payload), 
  "secret string"
);

下面是對這裏發生的情況做解釋:

首先, HMACSHA256 是哈希函數的名稱, 並帶有兩個參數:要散列的字符串,以及「secret」。

其次,我們哈希的字符串是 base 64 的編碼報頭,加上 base 64 的編碼有效載荷。

第三, secret 是任意一段字符串,只有服務器知道。

問. 為什麼在簽名散列中包含標頭和有效負載?

這確保了簽名對於此特定令牌是唯一的。*

問. secret 是什麼?

為了回答這個問題,讓我們考慮一下如何偽造令牌。

我們之前說過,您無法通過查看輸出來確定哈希的輸入。但是,由於我們知道簽名包括標頭和有效負載,因為它們是公共信息,所以如果您知道哈希算法(提示:通常在標頭中指定),則可以生成相同的哈希。

但是只有服務器知道的秘密 不是 公共信息。將其包含在哈希中可防止某人生成自己的哈希來偽造令牌。而且由於散列會掩蓋用於創建散列的信息,因此任何人都無法從散列中找出秘密。

將私有數據添加到哈希中的過程稱為 salting 
,幾乎不可能破解令牌。

認證過程

因此,現在您對令牌的創建方式有了一個很好的了解。您如何使用它來驗證您的API?

登錄

用戶登錄時會生成令牌,令牌會與用戶模型一起存儲在數據庫中。

  • loginController.js *
if (passwordCorrect) { 
  user.token = generateToken(user.id); 
  user.save(); 
}

然後令牌作為authorization頭附加到登錄請求的響應中。

loginController.js

if (passwordCorrect) { 
  user.token = generateToken(user.id); 
  user.save(); 
  res.headers("authorization", `Bearer ${token}`).send(); 
}

驗證請求

現在,客戶端有了令牌,他們可以將其附加到任何將來的請求以身份驗證用戶。

當服務器收到帶有授權令牌的請求時,將發生以下情況:

1.它解碼令牌並從有效載荷中提取ID。

2.它使用此ID在數據庫中查找用戶。

3.它將請求令牌與用戶模型中存儲的令牌進行比較。如果它們匹配,則對用戶進行身份驗證。

authMiddleware.js

const token = req.header.token; 
const payload = decodeToken(token); 
const user = User.findById(payload.id); 
if (user.token = token) { 
  // 通過身份認證
} else {
 // 未通過身份認證
}

退出登錄

如果用戶註銷,只需刪除附加到用戶模型的令牌,現在令牌將不再起作用。用戶將需要再次登錄以生成新令牌。

logoutController.js

user.token = null; 
user.save();

總結

因此,這是關於如何使用 JSON Web 令牌保護 API 的最基本的說明。希望你不會很頭疼。

不過,相關的話題還有很多,所以這裡有一些額外的讀物:

  • JWT.io
  • 什麼是 JSON Web 令牌?
  • 了解如何使用 JSON Web 令牌 ( JWT ) 進行身份驗證

原文鏈接:https://learnku.com/laravel/t…

討論請前往專業的 Laravel 開發者論壇:https://learnku.com/Laravel  

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7498