1.JWT原理
- JWT 的原理是塑陵,服務器認證以后感憾,生成一個 JSON 對象蜡励,發(fā)回給用戶令花,就像下面這樣阻桅。
{
"姓名": "張三",
"角色": "管理員",
"到期時間": "2018年7月1日0點0分"
}
以后,用戶與服務端通信的時候兼都,都要發(fā)回這個 JSON 對象嫂沉。服務器完全只靠這個對象認定用戶身份。為了防止用戶篡改數(shù)據(jù)扮碧,服務器在生成這個對象的時候趟章,會加上簽名,服務器就不保存任何 session
數(shù)據(jù)了慎王,也就是說蚓土,服務器變成無狀態(tài)了,從而比較容易實現(xiàn)擴展赖淤。
2.JWT數(shù)據(jù)結(jié)構(gòu)
- 組成結(jié)構(gòu)
Header(頭部)
Payload(負載)
Signature(簽名)
-
舉例
它是一個很長的字符串蜀漆,中間用點(.)分隔成三個部分。注意咱旱,JWT 內(nèi)部是沒有換行的确丢,這里只是為了便于展示,將它寫成了幾行吐限。
image.png
image.png
2.1 Header
Header 部分是一個 JSON 對象鲜侥,描述 JWT 的元數(shù)據(jù)
{
"alg": "HS256",
"typ": "JWT"
}
上面代碼中,alg屬性表示簽名的算法algorithm
诸典,默認是 HMAC SHA256
(寫成 HS256)描函;typ屬性表示這個令牌(token)的類型(type),JWT 令牌統(tǒng)一寫為JWT狐粱。
2.2 Payload
Payload 部分也是一個 JSON 對象赘阀,用來存放實際需要傳遞的數(shù)據(jù)。JWT 規(guī)定了7個官方字段脑奠,供選用基公。
iss (issuer):簽發(fā)人
exp (expiration time):過期時間
sub (subject):主題
aud (audience):受眾
nbf (Not Before):生效時間
iat (Issued At):簽發(fā)時間
jti (JWT ID):編號
這個 JSON 對象也要使用 Base64URL 算法轉(zhuǎn)成字符串。
2.3 Signature
Signature 部分是對前兩部分的簽名宋欺,防止數(shù)據(jù)篡改轰豆。首先,需要指定一個密鑰(secret)齿诞。這個密鑰只有服務器才知道酸休,不能泄露給用戶。然后祷杈,使用 Header 里面指定的簽名算法(默認是 HMAC SHA256)斑司,按照下面的公式產(chǎn)生簽名。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
算出簽名以后但汞,把 Header宿刮、Payload互站、Signature 三個部分拼成一個字符串,每個部分之間用"點"(.)分隔僵缺,就可以返回給用戶胡桃。
2.4 Base64URL
JWT 作為一個令牌(token),有些場合可能會放到 URL(比如 api.example.com/?token=xxx)磕潮。Base64 有三個字符+
翠胰、/
和=
,在 URL 里面有特殊含義自脯,所以要被替換掉:=被省略之景、+
替換成-
,/
替換成_
膏潮。這就是 Base64URL 算法闺兢。
3.使用方式
- 客戶端收到服務器返回的 JWT,可以儲存在 Cookie 里面戏罢,也可以儲存在 localStorage屋谭。此后,客戶端每次與服務器通信龟糕,都要帶上這個
JWT
桐磁。你可以把它放在 Cookie 里面自動發(fā)送,但是這樣不能跨域讲岁,所以更好的做法是放在 HTTP 請求的頭信息Authorization
字段里面
Authorization: Bearer <token>
另一種做法是我擂,跨域的時候,JWT 就放在 POST 請求的數(shù)據(jù)體里面缓艳。
4.特點
- JWT 默認是不加密校摩,但也是可以加密的。生成原始 Token 以后阶淘,可以用密鑰再加密一次衙吩。
- JWT 不加密的情況下,不能將秘密數(shù)據(jù)寫入 JWT溪窒。
- JWT 不僅可以用于認證坤塞,也可以用于交換信息。有效使用 JWT澈蚌,可以降低服務器查詢數(shù)據(jù)庫的次數(shù)摹芙。
- JWT 的最大缺點是,由于服務器不保存 session 狀態(tài)宛瞄,因此無法在使用過程中廢止某個 token浮禾,或者更改 token 的權(quán)限。也就是說,一旦 JWT 簽發(fā)了盈电,在到期之前就會始終有效蝴簇,除非服務器部署額外的邏輯。
- JWT 本身包含了認證信息挣轨,一旦泄露,任何人都可以獲得該令牌的所有權(quán)限轩猩。為了減少盜用卷扮,JWT 的有效期應該設置得比較短。對于一些比較重要的權(quán)限均践,使用時應該再次對用戶進行認證晤锹。
- 為了減少盜用,JWT 不應該使用 HTTP 協(xié)議明碼傳輸彤委,要使用 HTTPS 協(xié)議傳輸鞭铆。