周虎



摘? 要:JWT(JsonWebToken)認證作為一種服務器端無狀態驗證方式,在分布式開發中得到了廣泛的應用。但是,由于token信息的本身特點,支持的有效時間是固定的,當在token有效時間內用戶操作沒有完成,操作就會中斷,需要重新登錄驗證。本文通過對比傳統Cookie/Session身份驗證機制在分布式開發中存在的不足,提出了一種基于JWT認證過程中動態刷新token的方法,有效地解決了分布式開發中會話共享問題,并通過在webApi開發中得到了具體的應用,表明了該方法的有效性和實用性。
關鍵詞:JWT;token;認證;webApi
中圖分類號:TP311.11? ? ?文獻標識碼:A
Research on a Refresh Mechanism of Authentication Token Based on JWT
ZHOU Hu
(Xuzhou Finance and Economics Branch,Jiangsu Union Technical Institute,Xuzhou 221008,China)
Abstract:JWT (JSON Web Token) authentication,as a server-side stateless authentication method,has been widely used in distributed development.However,due to the characteristics of token information itself,the supported valid time is fixed.When the user operation is not completed within the token valid time,the operation will be interrupted and the login verification needs to be re-registered.By comparing the traditional Cookie/Session authentication mechanism in distributed development of deficiencies,this paper proposes a method based on dynamic refresh token JWT certification process,solving effectively the problem of the sharing Session in distributed development.The application in the webApi development shows that the method is effective and practical.
Keywords:JWT;token;authentication;webApi
1? ?引言(Introduction)
目前,隨著Web應用技術的不斷發展,應用程序的規模不斷擴大,分布式應用開發逐漸成了主流趨勢。傳統的Web程序認證技術基于Session和cookie技術的弊端已經逐步顯露出來,在多臺服務器之間如何實現會話共享,保持會話一致,即使實現了會話復制,隨著服務器數量的不斷增加,Session復制性能也會急劇下降[1],給服務器的性能帶來損失,它們已經不能滿足現代Web應用程序的發展需要。客戶端和服務器端會話分離,保持服務器端無狀態提供服務,同時又要保證服務器端資源的安全性,為了克服這些不足,基于JWT認證技術得到了廣泛關注,其通過特定的算法生成用戶唯一的令牌token對象,然后在用戶數據請求過程中攜帶此token即可完成身份有效性校驗,一方面保證了前后端分離,同時保護用戶訪問安全[2]。它與Session機制最大的區別就是一個將用戶認證信息保存在服務器端,一個保存在客戶端,大大減輕了服務器端的存儲壓力,同時提供了跨域訪問和分布式服務器集群訪問的身份認證。
基于JWT的認證方式雖然給身份認證方式帶來了極大的方便,但是也存在一些弊端,當服務器端簽發token時,它包含了簽發時間和失效時間,當在有效時間內,如果用戶操作沒有完成,服務器端將要求客戶端重新登錄,一方面可能導致數據丟失,同時給用戶體驗造成了負面影響。所以針對這種情況,本文提出了一種基于客戶端異步刷新token方式,一方面延長了token的有效時間,同時改善了用戶體驗,并通過JWT結合.netCore中的WebApi技術證明了該方法的可行性。
2? ?JWT(Json Web Token)
JWT是一種基于Json格式Web token,定義了一個緊湊的自包含的方式在不同實體之間安全傳輸信息[3]。它是在Web環境下兩個實體之間傳輸數據的一項標準。實際上傳輸的就是一個字符串。token信息包含了三個部分:HEAD頭部,用來聲明token類型和加密的算法;PAYLOAD載荷部分,主要用于傳遞信息的載體,常用的有iss(簽發者)、iat(簽發時間)、exp(過期時間)、sub(面向的用戶)、aud(接收方);SIGNATURE部分,用于將Header和Payload編碼后的字符串拼接后再用HS256簽名算法(Header中alg指明的算法)加密,在加密的過程中還需加上secret(密鑰),最后得到簽名,具體結構如圖1所示。
對于JWT認證方式,首先由客戶端發起用戶登錄請求,在服務端進行用戶信息驗證,驗證成功后,將給客戶端簽發token,簽發成功后,客戶端將簽發的token保存到客戶端,在進行服務器資源訪問時,需要在請求頭中放置簽發的token,服務器端接收到客戶端發送的token時,對其進行驗證是否合法,是否在有效時間內,如果在有效時間內并且用戶身份合法,將返回服務器資源,具體流程如圖2所示。
基于JWT的認證方式,由于Json的通用性,所以JWT是可以進行跨語言支持,有了PAYLOAD部分,所以JWT可以在自身存儲一些其他業務邏輯所必要的非敏感信息。JWT構成非常簡單,字節占用很小,所以它是非常便于傳輸的,并且不在服務端保存會話信息,更易于應用的擴展[4]。
3? token動態刷新功能的實現(Implementation of token dynamic refresh function)
當客戶端發出認證請求,服務端接收客戶端發送的用戶信息并驗證合法性,驗證通過后給客戶端返回頒發的token、頒發時間和失效時間,客戶端根據接收的信息,計算客戶端當前時間和token的頒發時間的時間偏差,將token、頒發時間、失效時間和時間偏差保存到瀏覽器的localstorage中。客戶端在進行WebApi訪問時,客戶端從localstorage中取出信息計算當前時間加上時間偏差并和token的失效時間進行比較,如果距離失效時間不在限定時間范圍內(比如2分鐘),直接進行請求WebApi,否則,先進行異步請求登錄認證,然后在進行WebApi請求[5],具體流程如圖3所示。
當客戶端重新請求時,服務器端將重新頒發token,并將頒發時間、失效時間和客戶端的時間偏差值重新保存到客戶端的localstorage中,再次請求WebApi時將攜帶新的token。
為了驗證客戶端動態刷新token功能,本文采用JWT結合.netCore平臺中的WebApi技術,實現對客戶端訪問控制,主要實現兩個部分:服務端認證并簽發token和客戶端請求token。
3.1? ?服務端認證并簽發token
當客戶端發送請求用戶名和密碼進行驗證時,服務器端先驗證用戶的合法性,如果用戶合法,將給用戶頒發token,實現代碼如下:
if (validateUser(userInfo)//驗證用戶合法
{
long curTime=DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
long endTime=DateTimeOffset.UtcNow.AddMinutes(20).ToUnixTimeMilliseconds();
LoginInfo pUserLoginInfo=new LoginInfo() { Name=UserName,Password=PassWord,exp=endTime };
var token=new JwtBuilder()//簽發token
.WithAlgorithm(new HMACSHA256Algorithm())//指定算法
.WithSecret(m_Secret)//密鑰
.ExpirationTime(DateTime.UtcNow.AddMinutes(5))//過期時間
.AddClaim("issuser","xzcx")//頒發者
.AddClaim("audience",userInfo.Name)//接收者
.Build();
jwtResult=new JwtResult()
{
token=token,
statusCode="200",
message="success",
assTime=curTime,//簽發時間
endTime=endTime
};
return JsonConvert.SerializeObject(jwtResult);
}
當服務器端簽發token時,指定簽發時間和失效時間,在上面程序中,指定token失效時間為當前時間后20分鐘,并且所有時間格式按照Unix格式時間戳來保存。簽發token成功后將token和狀態碼,返回消息以及簽發時間和失效時間以JSON格式響應到客戶端[6]。
3.2? ?客戶端保存token并請求WebApi
當客戶端接收到服務端響應的token信息,將其保存到客戶端的localstorage中,實現代碼如下:
$.ajax({
url:'https://localhost:44337/api/service',
data:{UserName:username,PassWord:password},
success:function (data) {
var result=$.parseJSON(data);
localStorage.setItem("token",result.token);//保存token
localStorage.setItem("assTime",result.assTime);//保存頒發時間
localStorage.setItem("endTime",result.endTime);//保存失效時間
localStorage.setItem("offsetTime",new Date().getTime()-result.curTime);//保存客戶端和服務端時間差
}
})
當用戶請求WebApi時,將從localstorage中取出token信息,并加入請求head中,但是,在請求前需要判斷一下當前時間和token的失效時間差是否在設定時間內,如果在設定內,需要重新請求認證并保存新的token,然后再次訪問WebApi[7],實現代碼如下:
var token=localStorage.getItem("token");
var curTime=localStorage.getItem("curTime");
var offsetTime=localStorage.getItem("offsetTime");
var endTime=localStorage.getItem("endTime");
if ((parseInt(endTime)-(new Date().getTime()+parseInt(offsetTime))<120000)) {//如果時間差在2分鐘以內則重新請求認證
var promise=new Promise(function (resolve,reject) {
login()//重新登錄驗證
})
promise.then(visitApi(url));? ?//請求成功后再訪問WebApi
}
else {
visitApi(url);//如果時間差大于2分鐘直接訪問WebApi
}
在實現重新請求認證時,需要用到Promise對象,因為在重新請求認證和訪問WebApi時有先后順序,必須要等到服務端重新頒發token并且客戶端保存成功后再次攜帶新的token訪問WebApi,否則將訪問失敗。經過測試發現,客戶端動態刷新token方法在不影響用戶操作體驗的情況下動態延長token有效期限,有效地解決了token失效問題[8]。
4? ?結論(Conclusion)
本文通過對目前基于JWT認證機制下token失效問題進行了深入研究,為了更好保證在不影響用戶操作的前提下,動態延長token的有效期限,提出了一種基于客戶端在設定時間內動態刷新token的方法,并在.netCore平臺下的WebApi技術中得到了具體的驗證,該方法簡單有效地解決了token失效問題,同時大大減輕了服務器端的負擔,也為前后端分離提供有效地解決方案[9]。
參考文獻(References)
[1] 柳綱,張毅.服務端無狀態技術研究[J].電力信息與通信技術,2017(11):49-54.
[2] 陳宇收,饒宏博,王英明,等.基于JWT 的前后端分離程序設計研究[J].電腦編程技巧與維護,2019(09):11-12.
[3] 范展源,羅福強.JWT認證技術及其在Web中的應用[J].數字技術與應用,2016(02):114.
[4] 項武銘,鮑亮,俞少華.基于JWT的RESTful API角色權限驗證方案設計[J].現代計算機(專業版),2018(12):82-85.
[5] 黃偉民,陳可新.基于Token的物聯網云平臺系統身份認證機制研究[J].智庫時代,2018(42):195-196.
[6] 王威.物聯網的體系結構與相關技術[J].電子技術與軟程,2018(22):14-15.
[7] 王守昌.JWT從入門到精通[EB/OL].https://www.cnblogs.com/wangshouchang/p/9551748.html,2018-08-28.
[8] LIU Gang,HE Jing.Design of a high performance WEB cluster[J].Electric Power Information and Communication Technology,2017,15(3):95-100.
[9] Woo-Suk Park,Dong-Yeop Hwang.A TOTP-Based Two Factor Authentication Scheme for Hyperledger Fabric Blockchain[J].2018 Tenth International Conference on Ubiquitous and Future Networks(ICUFN),2018(05):78-81.
作者簡介:
周? 虎(1977-),男,碩士,講師.研究領域:應用程序設計.