摘要:在使用非對稱加密算法進行簽名的時候,還可以用于驗證的發件人是否與中申明的發件人是同一個人。如果沒有用非對稱加密算法的話,把復制之后直接可以去官網在線解析。
這篇博客主要是簡單介紹了一下什么是JWT,以及如何在Spring Boot項目中使用JWT(JSON Web Token)。
1.關于JWT 1.1 什么是JWT老生常談的開頭,我們要用這樣一種工具,首先得知道以下幾個問題。
這個工具是什么,這個工具解決了什么問題
是否適用于當前我們所處得業務場景
用了之后是否會帶來任何其他問題
怎么用才是最佳實踐
那什么是JWT呢?以下是我對jwt官網上對JWT介紹的翻譯。
JSON Web Token (JWT)是一種定義了一種緊湊并且獨立的,用于在各方之間使用JSON對象安全的傳輸信息的一個開放標準(RFC 7519)。
現在我們知道,JWT其實是一種開放標準,用于在多點之間安全地傳輸用JSON表示的數據。在傳輸的過程中,JWT以字符串的形式出現在我們的視野中。該字符串中的信息可以通過數字簽名進行驗證和信任。
1.2 應用場景JWT在實際的開發中,有哪些應用場景呢?
1.2.1 授權這應該算是JWT最常見的使用場景。在前端界面中,一旦用戶登錄成功,會接收到后端返回的JWT。后續的請求都會包含后端返回的JWT,作為對后端路由、服務以及資源的訪問的憑證。
1.2.2 信息交換利用JWT在多方之間相互傳遞信息具有一定的安全性,例如JWT可以用HMAC、RSA非對稱加密算法以及ECDSA數字簽名算法對JWT進行簽名,可以確保消息的發送者是真的發送者,而且使用header和payload進行的簽名計算,我們還可以驗證發送的消息是否被篡改了。
2.JWT的結構通俗來講JWT由header.payload.signature三部分組成的字符串,網上有太多帖子介紹這一塊了,所以在這里就簡單介紹一下就好了。
2.1 headerheader由使用的簽名算法和令牌的類型的組成,例如令牌的類型就是JWT這種開放標準,而使用的簽名算法就是HS256,也就是HmacSHA256算法。其他的加密算法還有HmacSHA512、SHA512withECDSA等等。
然后將這個包含兩個屬性的JSON對象轉化為字符串然后使用Base64編碼,最終形成了JWT的header。
2.2 payloadpayload說直白一些就類似你的requestBody中的數據。只不過是分了三種類型,預先申明好的、自定義的以及私有的。像iss發件人,exp過期時間都是預先注冊好的申明。
預先申明在載荷中的數據不是強制性的使用,但是官方建議使用。然后這串類似于requestBody的JSON經過Base64編碼形成了JWT的第二部分。
2.3 signature如果要生成signature,就需要使用jwt自定義配置項中的secret,也就是Hmac算法加密所需要的密鑰。將之前經過Base64編碼的header和payload用.相連,再使用自定義的密鑰,對該消息進行簽名,最終生成了簽名。
生成的簽名用于驗證消息在傳輸的過程中沒有被更改。在使用非對稱加密算法進行簽名的時候,還可以用于驗證JWT的發件人是否與payload中申明的發件人是同一個人。
3.JWT在Spring項目中的應用場景 3.1 生成JWT代碼如下。
public String createJwt(String userId, String projectId) throws IllegalArgumentException, UnsupportedEncodingException { Algorithm al = Algorithm.HMAC256(secret); Instant instant = LocalDateTime.now().plusHours(outHours).atZone(ZoneId.systemDefault()).toInstant(); Date expire = Date.from(instant); String token = JWT.create() .withIssuer(issuer) .withSubject("userInfo") .withClaim("user_id", userId) .withClaim("project_id", projectId) .withExpiresAt(expire) .sign(al); return token; }
傳入的兩個Claim是項目里自定義的payload,al是選擇的算法,而secret就是對信息簽名的密鑰,subject則是該token的主題,withExpiresAt標識了該token的過期時間。
3.2 返回JWT在用戶登錄系統成功之后,將token作為返回參數,返回給前端。
3.3 驗證token在token返回給前端之后,后端要做的就是驗證這個token是否是合法的,是否可以訪問服務器的資源。主要可以通過以下幾種方式去驗證。
3.3.1 解析token使用JWTVerifier解析token,這是驗證token是否合法的第一步,例如前端傳過來的token是一串沒有任何意義的字符串,在這一步就可以拋出錯誤。示例代碼如下。
try { Algorithm algorithm = Algorithm.HMAC256(secret); JWTVerifier verifier = JWT.require(algorithm).build(); DecodedJWT jwt = verifier.verify(token); } catch (JWTVerificationException e) { e.printStackTrace(); }
JWTVerifier可以使用用制定secret簽名的算法,指定的claim來驗證token的合法性。
3.3.2 判斷token時效性判斷了token是有效的之后,再對token的時效性進行驗證。
try { Algorithm algorithm = Algorithm.HMAC256(secret); JWTVerifier verifier = JWT.require(algorithm).build(); DecodedJWT jwt = verifier.verify(token); if (jwt.getExpiresAt().before(new Date())) { System.out.println("token已過期"); return null; } } catch (JWTVerificationException e) { e.printStackTrace(); return null; }
如果該token過期了,則不允許訪問服務器資源。具體的流程如下。
3.3.3 刷新過期時間上面創建token的有效時間是可以配置的,假設是2個小時,并且用戶登錄進來連續工作了1小時59分鐘,在進行一個很重要的操作的時候,點擊確定,這個時候token過期了。如果程序沒有保護策略,那么用戶接近兩個小時的工作就成為了無用功。
遇到這樣的問題,我們之前的流程設計必然面對一次重構。可能大家會有疑問,不就是在用戶登錄之后,每次操作對去刷新一次token的過期時間嗎?
那么問題來了,我們知道token是由header.payload.signature三段內容組成的,而過期時間則是屬于payload,如果改變了過期的時間,那么最終生成的payload的hash則勢必與上一次生成的不同。
換句話說,這是一個全新的token。前端要怎么接收這個全新的token呢?可想到的解決方案無非就是每次請求,根據response header中的返回不斷的刷新的token。但是這樣的方式侵入了前端開發的業務層。使其每一個接口都需要去刷新token。
大家可能會說,無非就是加一個攔截器嘛,對業務侵入不大啊。即使這部分邏輯是寫在攔截器里的,但是前端因為token鑒權的邏輯而多出了這部分代碼。而這部分代碼從職能分工上來說,其實是后端的邏輯。
說的直白一些,刷新token,對token的時效性進行管理,應該是由后端來做。前端不需要也不應該去關心這一部分的邏輯。
3.3.4 redis大法好綜上所述,刷新token的過期時間勢必要放到后端,并且不能通過判斷JWT中payload中的expire來判斷token是否有效。
所以,在用戶登錄成功之后并將token返回給前端的同時,需要以某一個唯一表示為key,當前的token為value,寫入Redis緩存中。并且在每次用戶請求成功后,刷新token的過期時間,流程如下所示。
經過這樣的重構之后,流程就變成了這樣。
在流程中多了一個刷新token的流程。只要用戶登錄了系統,每一次的操作都會刷新token的過期時間,就不會出現之前說的在進行某個操作時突然失效所造成數據丟失的情況。
在用戶登錄之后的兩個小時內,如果用戶沒有進行任何操作,那么2小時后再次請求接口就會直接被服務器拒絕訪問。
4.總結總的來說,JWT中是不建議放特別敏感信息的。如果沒有用非對稱加密算法的話,把token復制之后直接可以去jwt官網在線解析。如果請求被攔截到了,里面的所有信息等于是透明的。
但是JWT可以用來當作一段時間內運行訪問服務器資源的憑證。例如JWT的payload中帶有userId這個字段,那么就可以對該token標識的用戶的合法性進行驗證。例如,該用戶當前狀態是否被鎖定?該userId所標識的用戶是否存在于我們的系統?等等。
并且通過實現token的公用,可以實現用戶的多端同時登錄。像之前的登錄之后創建token,就限定了用戶只能同時在一臺設備上登錄。
歡迎大家瀏覽之前的文章:個人博客,如果有說的不對的地方,還請不吝賜教。
5.參考JWT官網
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73766.html
摘要:框架具有輕便,開源的優點,所以本譯見構建用戶管理微服務五使用令牌和來實現身份驗證往期譯見系列文章在賬號分享中持續連載,敬請查看在往期譯見系列的文章中,我們已經建立了業務邏輯數據訪問層和前端控制器但是忽略了對身份進行驗證。 重拾后端之Spring Boot(四):使用JWT和Spring Security保護REST API 重拾后端之Spring Boot(一):REST API的搭建...
摘要:今天我們來結合實例給大家講述的實戰應用,就是如何使用前端與后端實現用戶登錄鑒權認證的過程。只用了一個串,建立前后端的驗證的數據傳遞,實現了有效的登錄鑒權過程。 今天我們來結合實例給大家講述JWT(Json Web Token)的實戰應用,就是如何使用前端Axios與后端PHP實現用戶登錄鑒權認證的過程。 文中涉及的重要知識點: axios異步請求:axios-基于Promise的HTT...
摘要:小程序官方流程圖如下,官方地址如果此圖理解不清楚的地方也可參看我的博客本文是對接微信小程序自定義登錄的一個完整例子實現,技術棧為。調用微信接口獲取和根據和自定義登陸態返回自定義登陸態給小程序端。 小程序官方流程圖如下,官方地址 : https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login....
摘要:作為目前最主流的微服務框架,發展速度很快,成為了最全面的微服務解決方案。通過認證后,轉發給內部相應的服務器。所有遠程訪問資源服務器相關的必須提供。 Part 1 - 理論相關 作者 freewolf 關鍵詞 微服務、Spring Cloud、OAuth 2.0、JWT、Spring Security、SSO、UAA 寫在前面 作為從業了十多年的IT行業和程序的老司機,今天如果你說你不懂...
閱讀 1303·2021-11-11 10:57
閱讀 3717·2021-09-07 10:10
閱讀 3442·2021-08-03 14:03
閱讀 3067·2019-08-30 13:45
閱讀 681·2019-08-29 11:19
閱讀 1038·2019-08-28 18:07
閱讀 3099·2019-08-26 13:55
閱讀 808·2019-08-26 12:17