天天看點

JWT基礎

參考:JWT——概念、認證流程、結構、使用JWT_Guizy-CSDN部落格

一、什麼是JWT

JWT簡稱

JSON Web Token

,也就是通過JSON形式作為Web應用中的令牌,用于在各方之間安全地将資訊作為

JSON對象

傳輸。在資料傳輸過程中還可以完成

資料加密

簽名

等相關處理。

二、JWT能做什麼?

1、授權

這是使用JWT的最常見方案。一旦使用者登入,每個後續請求将包括JWT,進而允許使用者通路該令牌允許的路由,服務和資源。單點登入是當今廣泛使用JWT的一項功能,因為它的開銷很小并且可以在不同的域中輕松使用。

2、資訊交換

JSON Web Token是在各方之間安全地傳輸資訊的好方法。因為可以對JWT進行簽名(例如,使用公鑰/私鑰對),是以您可以確定發件人是他們所說的人。此外,由于簽名是使用标頭和有效負載計算的,是以您還可以驗證内容是否遭到篡改。

三、JWT工作流程

JWT基礎

四、JWT結構

JWT令牌

 = 

Header.Payload.Signature

JWT令牌組成 :

  • 1.Header
  • 2.Payload
  • 3.Signature

是以,JWT通常如下所示:xxxxx.yyyyy.zzzzz

1、Header

  • 标頭通常由兩部分組成:令牌的類型(即JWT)和所使用的簽名算法,例如HMAC SHA256或RSA。它會使用 

    Base64

    編碼

    組成 JWT 結構的

    第一部分`。
  • 注意:Base64是一種編碼,也就是說,它是可以被翻譯回原來的樣子來的。它并不是一種加密過程。

如下面是一串token,我們解析一下:

eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJsUnpNWXVwemNZUm9iTnMyZnpqdEtMX3BNZGhSS0JIdnJfTDRHMWpuR3hnIn0
.eyJqdGkiOiJjNTdjOTkwYS01ZDY1LTRhNmItODUyMS1lZjc5NDViNmQ3OTkiLCJleHAiOjE2MzQxNDU5NjcsIm5iZiI6MCwiaWF0IjoxNjM0MTEwMTcwLCJpc3MiOiJodHRwOi8vaWFtYXV0aC5pYW10ZXN0LnByZC51aW1wY2xvdWQuY29tL2F1dGgvcmVhbG1zL2J1c2luZXNzIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6ImIyNTkwYzQ0LWM1MWItNDRkOS04NTQ3LTcwZDI2NTEwYzIxOSIsInR5cCI6IkJlYXJlciIsImF6cCI6InVpbXBjbG91ZC1mcm9udGVuZCIsIm5vbmNlIjoiNjVhODNkNzYtZTNiMy00NzhmLWFhMDktOTFmMTU5MzlkODNlIiwiYXV0aF90aW1lIjoxNjM0MTA5OTY3LCJzZXNzaW9uX3N0YXRlIjoiM2U1ZjRkNTUtMmY3Ni00NmMzLWJkNDEtNDhlNzljOWMwZGU2IiwiYWNyIjoiMCIsImFsbG93ZWQtb3JpZ2lucyI6WyIqIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6IueuoeeQhuWRmCDnrqEiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImdpdmVuX25hbWUiOiLnrqHnkIblkZgiLCJsb2NhbGUiOiJ6aC1DTiIsImZhbWlseV9uYW1lIjoi566hIn0
.aIKWuiP9_ENFi_cQBKsMxhuQkU6kkE49xLwYQuFucsctiUaDOnVh45NJ9mFKUlqMIuEzGwihTQoyI2Te8VnmWsCvTzODZHufUQDSYDvnwCXm1R9XBLL4b8x63z_c9_G6In6xspyhzVse5N8BTlzm4Vro0t_5pUltbW5O0_rBKeZ_7aC6nPLR6CQpibR1FFQfoSJO_qavwNudZKKycX4PrIWDRobfeJAWUY-AA3YtNjqlm8s46bcVairHQc98CInvEgSohe7Hz-pkBqXmDKsrQmv-VwQ7G5-LE-IpIr3UAugdUoKeL3J0Z0O2pf4856QsIwYe2dInh22HyNJSBfp9Rw
           

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9,就是header,我們用base64解析一下,得到:

JWT基礎
{
	"alg": "RS256",
	"typ": "JWT",
	"kid": "lRzMYupzcYRobNs2fzjtKL_pMdhRKBHvr_L4G1jnGxg"
}
           

2、Payload

  • 令牌的第二部分是有效負載,其中包含聲明。聲明是有關實體(通常是使用者)和其他資料的聲明(

    存放使用者資訊的

    )。同樣的,它會使用 

    Base64 編碼

    組成 JWT 結構的

    第二部分

{
	"jti": "c57c990a-5d65-4a6b-8521-ef7945b6d799",
	"exp": 1634145967,
	"nbf": 0,
	"iat": 1634110170,
	"iss": "http://iamauth.iamtest.prd.uimpcloud.com/auth/realms/business",
	"aud": "account",
	"sub": "b2590c44-c51b-44d9-8547-70d26510c219",
	"typ": "Bearer",
	"azp": "uimpcloud-frontend",
	"nonce": "65a83d76-e3b3-478f-aa09-91f15939d83e",
	"auth_time": 1634109967,
	"session_state": "3e5f4d55-2f76-46c3-bd41-48e79c9c0de6",
	"acr": "0",
	"allowed-origins": ["*"],
	"realm_access": {
		"roles": ["offline_access", "uma_authorization"]
	},
	"resource_access": {
		"account": {
			"roles": ["manage-account", "manage-account-links", "view-profile"]
		}
	},
	"scope": "openid profile email",
	"email_verified": false,
	"name": "管理者 管",
	"preferred_username": "admin",
	"given_name": "管理者",
	"locale": "zh-CN",
	"family_name": "管"
}
           

3、Signature

前面兩部分都是使用 Base64 進行編碼的,即前端可以解開知道裡面的資訊。Signature 需要使用編碼後的 header 和 payload 以及我們提供的一個密鑰,然後使用 header 中指定的簽名算法(HS256)進行簽名。簽名的作用是保證 JWT 沒有被篡改過

base64(header) . base64(payload) . "#**[email protected]"(秘鑰) -----> 組成 Signature

WT令牌 = base64(header) . base64(payload) . Signature

eg :

假如我們的JWT令牌傳回給用戶端了, 結構為base64(header).base64(payload).aaaaa, aaaaa是簽名, 由base64(header) . base64(payload) . 密鑰生成的, 用戶端此時拿到了這個Token;

jwt會先驗簽, 用戶端拿到token去請求資料, 首先服務端會先将該token的Signature和aaaaa作比對, 如果确實相同, 則該令牌是正确的;

這種做法就是為了防止篡改資料, 如果修改了header, payload, 生成的Signature都和服務端的對不上, 就會驗證該令牌是非法的;

簽名目的

最後一步簽名的過程,實際上是對頭部以及負載内容進行簽名,防止内容被竄改。如果有人對頭部以及負載的内容解碼之後進行修改,再進行編碼,最後加上之前的簽名組合形成新的JWT的話,那麼伺服器端會判斷出新的頭部和負載形成的簽名和JWT附帶上的簽名是不一樣的。如果要對新的頭部和負載進行簽名,在不知道伺服器加密時用的密鑰的話,得出來的簽名也是不一樣的。

資訊安全問題

在這裡大家一定會問一個問題:Base64是一種編碼,是可逆的,那麼我的資訊不就被暴露了嗎?

是的。是以,在JWT中,不應該在負載裡面加入任何敏感的資料。在上面的例子中,我們傳輸的是使用者的User ID。這個值實際上不是什麼敏感内容,一般情況下被知道也是安全的。但是像密碼這樣的内容就不能被放在JWT中了。如果将使用者的密碼放在了JWT中,那麼懷有惡意的第 三方通過Base64解碼就能很快地知道你的密碼了。是以JWT适合用于向Web應用傳遞一些非敏感資訊。JWT還經常用于設計使用者認證和授權系統,甚至實作Web應用的單點登入。

JWT基礎

繼續閱讀