一、Token
在計算機身份認(rèn)證中代表令牌,在服務(wù)端產(chǎn)生的。如果前端使用用戶名/密碼向服務(wù)端請求認(rèn)證,服務(wù)端認(rèn)證成功,那么在服務(wù)端會返回 Token 給前端。前端可以在每次請求的時候帶上 Token 證明自己的合法地位。
1.1、Jwt簡介
JWT(JSON Web Token)是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)。
它將用戶信息加密到token里,服務(wù)器不保存任何用戶信息。服務(wù)器通過使用保存的密鑰驗證token的正確性,只要正確即通過驗證;應(yīng)用場景如用戶登錄。
1.2、為什么有Jwt
目前主流的Web開發(fā)模式有兩種:
- 基于服務(wù)端渲染的傳統(tǒng)Web開發(fā)模式
- 基于前后端分離的新型Web開發(fā)模式
對于這兩種開發(fā)模式的身份認(rèn)證,服務(wù)端渲染推薦使用 Session認(rèn)證機制,前后端分離推薦使用JWT認(rèn)證機制。
對于傳統(tǒng)的session認(rèn)證,因為HTTP是無協(xié)議的,為了記住用戶狀態(tài),服務(wù)器在用戶第一次訪問時會返回一個cookie同時服務(wù)端保存一個對應(yīng)的session,但是這種基于session的認(rèn)證使應(yīng)用本身很難得到擴展,隨著不同客戶端用戶的增加,大量session會話的創(chuàng)建對服務(wù)器是一個巨大的開銷;
同時,當(dāng)服務(wù)端為集群時,用戶登錄其中一臺服務(wù)器,會將session保存在該服務(wù)器的內(nèi)存中,
只有再次訪問這臺服務(wù)器才能拿到授權(quán)資源。
另外session認(rèn)證機制依賴Cookie,但是Cookie默認(rèn)不支持跨域訪問,所以,當(dāng)涉及到前端跨域請求后端接口的時候,需要做很多額外的配置,才能實現(xiàn)跨域Session認(rèn)證。這就有了JWT的出現(xiàn),流程上是這樣的:
- 用戶使用用戶名密碼來請求服務(wù)器
- 服務(wù)器進行驗證用戶的信息
- 服務(wù)器通過驗證發(fā)送給用戶一個token
- 客戶端存儲token,并在每次請求時附送上這個token值
- 服務(wù)端驗證token值,并返回數(shù)據(jù)
1.3、Jwt Token結(jié)構(gòu)
JWT由三部分構(gòu)成,第一部分我們稱它為頭部(header),第二部分我們稱其為載荷(payload),第三部分是簽證(signature)。
- header:Header通常由兩部分組成:令牌的類型,即JWT。和常用的散列算法,如HMAC SHA256或RSA。
{
“typ”: “JWT”,
“alg”: “HS256”
}
由上可知,該token使用HS256加密算法,將頭部進行base64加密(該加密是可以對稱解密的),構(gòu)成了第一部分:
eyJhbGciOiJIUzI1NiJ91
-
Playload:載荷就是存放有效信息的地方,這些有效信息包含三個部分
1、 Registered claims(注冊聲明): 這些是一組預(yù)先定義的聲明,它們不是強制性的,但推薦使用,以提供一組有用的,可互操作的聲明。 其中一些是:iss(發(fā)行者),exp(到期時間),sub(主題),aud(受眾)等
2、Public claims (公開聲明): 公共的聲明可以添加任何的信息,一般添加用戶的相關(guān)信息或其他業(yè)務(wù)需要的必要信息.但不建議添加敏感信息,因為該部分在客戶端可解密。
3、Private claims(私有聲明): 私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息。
{
“iss”: “Online JWT Builder”,
“iat”: 1416797419,
“exp”: 1448333419,
…….
“userid”:10001
}
有效載荷中存放了token的簽發(fā)者(iss)、簽發(fā)時間(iat)、過期時間(exp)等以及一些我們需要寫進token中的信息。然后將其進行base64加密,得到Jwt的第二部分:
eyJ1c2VyaWQiOjB91
- Signature:這個部分需要base64加密后的header和base64加密后的payload使用,連接組成的字符串(頭部在前),然后通過header中聲明的加密方式進行加鹽secret組合加密,然后就構(gòu)成了jwt的第三部分。
例如頭部與載體加密拼接后的字符串為eyJhbGciOiJIUzI1NiJ91.eyJ1c2VyaWQiOjB91再次利用加密算法(HS256)與自定義的密鑰(secret)加密得到簽名部分字符:
rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM
將上面三個方法生成的字符串再次拼接就得到了完整的Token:
eyJhbGciOiJIUzI1NiJ91.eyJ1c2VyaWQiOjB91.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM
如果服務(wù)器應(yīng)用對頭部和載荷再次以同樣方法簽名之后發(fā)現(xiàn),自己計算出來的簽名和接受到的簽名不一樣,那么就說明這個Token的內(nèi)容被別人動過的,我們應(yīng)該拒絕這個Token
1.4、JWT的優(yōu)缺點
-
優(yōu)點:
1、因為json的通用性,所以JWT是可以進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。
2、payload可以在自身存儲一些其他業(yè)務(wù)邏輯所必要的非敏感信息。
3、它不需要在服務(wù)端保存會話信息, 所以它易于應(yīng)用的擴展 -
缺點:
1、安全性:由于JWT的payload是使用Base64編碼的,并沒有加密,因此JWT中不能存儲敏感數(shù)據(jù)。而Session的信息是存在服務(wù)端的,相對來說更安全。
2、一次性:無狀態(tài)是JWT的特點,但也導(dǎo)致了這個問題,JWT是一次性的。想修改里面的內(nèi)容,就必須簽發(fā)一個新的JWT。即缺陷是一旦下發(fā),服務(wù)后臺無法拒絕攜帶該jwt的請求(如踢除用戶)
二、Refresh Token
Token 是在服務(wù)端產(chǎn)生的。如果前端使用用戶名/密碼向服務(wù)端請求認(rèn)證,服務(wù)端認(rèn)證成功,那么在服務(wù)端會返回 Token 給前端。前端可以在每次請求的時候帶上 Token 證明自己的合法地位,而Token的playload部分一般會存儲相關(guān)的過期時間,一旦Token過期就會被攔截,因此如何設(shè)置Token刷新機制也是一個重點。
過長的過期時間會讓系統(tǒng)有長期暴露在接口的風(fēng)險,理論上過期時間越短越好,但是過短的時間明顯會帶來不好的用戶體驗。那么我們可以考慮使用Refresh Token刷新,一旦 Token 過期,就反饋給前端,前端使用 Refresh Token 申請一個全新 Token 繼續(xù)使用。
這種方案中,服務(wù)端只需要在客戶端請求更新 Token 的時候?qū)?Refresh Token 的有效性進行一次檢查,大大減少了更新有效期的操作,也就避免了頻繁讀寫。
2.1、實現(xiàn)原理
前端第一次發(fā)起請求時,后端準(zhǔn)備兩個 token,一個有效時間較短的作為認(rèn)證 token(token),一個有效時間較長的作為刷新 token(refreshToken),返回給前端。
前端拿到兩個 token 后,把它們都存儲在 localStorage 中,后面再次發(fā)起請求時攜帶兩個token:文章來源:http://www.zghlxwxcb.cn/news/detail-744718.html
- token 未過期時,可以正常請求。
- token 過期了,refreshToken 未過期,請求后端的刷新token接口對兩個token進行更新并返回給前端。
- token 和 refreshToken 均過期了,則用戶必須重新登錄。
2.2、代碼實現(xiàn)
demo:
Token refresh的實現(xiàn)文章來源地址http://www.zghlxwxcb.cn/news/detail-744718.html
到了這里,關(guān)于Token和Refresh Token的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!