JSON Web Token (JWT)是一個開放標準(RFC 7519),它定義了一種緊湊的、自包含的方式,用於做爲JSON對象在各方之間安全地傳輸信息。該信息能夠被驗證和信任,由於它是數字簽名的。git
下列場景中使用JSON Web Token是頗有用的:github
JSON Web Token由三部分組成,它們之間用圓點(.)鏈接。這三部分分別是:算法
所以,一個典型的JWT看起來是這個樣子的:數據庫
xxxxx.yyyyy.zzzzz後端
接下來,具體看一下每一部分:跨域
header典型的由兩部分組成:token的類型(「JWT」)和算法名稱(好比:HMAC SHA256或者RSA等等)。瀏覽器
例如:安全
而後,用Base64對這個JSON編碼就獲得JWT的第一部分服務器
JWT的第二部分是payload,它包含聲明(要求)。聲明是關於實體(一般是用戶)和其餘數據的聲明。聲明有三種類型: registered, public 和 private。cookie
下面是一個例子:
對payload進行Base64編碼就獲得JWT的第二部分
注意,不要在JWT的payload或header中放置敏感信息,除非它們是加密的。
爲了獲得簽名部分,你必須有編碼過的header、編碼過的payload、一個祕鑰,簽名算法是header中指定的那個,然對它們簽名便可。
例如:
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
簽名是用於驗證消息在傳遞過程當中有沒有被更改,而且,對於使用私鑰簽名的token,它還能夠驗證JWT的發送方是否爲它所稱的發送方。
看一張官網的圖就明白了:
在認證的時候,當用戶用他們的憑證成功登陸之後,一個JSON Web Token將會被返回。此後,token就是用戶憑證了,你必須很是當心以防止出現安全問題。通常而言,你保存令牌的時候不該該超過你所須要它的時間。
不管什麼時候用戶想要訪問受保護的路由或者資源的時候,用戶代理(一般是瀏覽器)都應該帶上JWT,典型的,一般放在Authorization header中,用Bearer schema。
header應該看起來是這樣的:
Authorization: Bearer <token>
服務器上的受保護的路由將會檢查Authorization header中的JWT是否有效,若是有效,則用戶能夠訪問受保護的資源。若是JWT包含足夠多的必需的數據,那麼就能夠減小對某些操做的數據庫查詢的須要,儘管可能並不老是如此。
若是token是在受權頭(Authorization header)中發送的,那麼跨源資源共享(CORS)將不會成爲問題,由於它不使用cookie。
下面這張圖顯示瞭如何獲取JWT以及使用它來訪問APIs或者資源:
在討論基於Token的身份認證是如何工做的以及它的好處以前,咱們先來看一下之前咱們是怎麼作的:
HTTP協議是無狀態的,也就是說,若是咱們已經認證了一個用戶,那麼他下一次請求的時候,服務器不知道我是誰,咱們必須再次認證
傳統的作法是將已經認證過的用戶信息存儲在服務器上,好比Session。用戶下次請求的時候帶着Session ID,而後服務器以此檢查用戶是否定證過。
這種基於服務器的身份認證方式存在一些問題:
相同點:它們都是存儲用戶信息;
不一樣點:一、Session是在服務器端的;而JWT是在客戶端的。
二、Session方式存儲用戶信息的最大問題在於要佔用大量服務器內存,增長服務器的開銷;
而JWT方式將用戶狀態分散到了客戶端中,能夠明顯減輕服務端的內存壓力。
三、Session的狀態是存儲在服務器端,客戶端只有session id;而Token的狀態是存儲在客戶端。
基於Token的身份認證是無狀態的,服務器或者Session中不會存儲任何用戶信息。
沒有會話信息意味着應用程序能夠根據須要擴展和添加更多的機器,而沒必要擔憂用戶登陸的位置。
雖然這一實現可能會有所不一樣,但其主要流程以下:
注意: