JWT令牌的工作原理詳解
JSON Web Tokens
在認(rèn)證的時(shí)候,當(dāng)用戶用他們的的憑證成功登錄以后,一個(gè)JSON Web Token將會被返回。
此后,用戶名和密碼就不再是用戶的憑證,而token是用戶用來訪問資源的新憑證了。
你必須非常小新以防止出現(xiàn)安全問題。一般而言,你保存令牌的時(shí)間不應(yīng)該超過你所需要它的時(shí)間。
無論何時(shí)用戶想要訪問受保護(hù)的路由或資源的時(shí)候,用戶代理(通常是瀏覽器)都應(yīng)該帶上JWT,典型的,通常放在Authorization header中,用Bearer Schema。
header看起來應(yīng)該是這樣的:
Authorization: Bearer [token]
服務(wù)器上的受保護(hù)的路由將會檢查Authorization header中的JWT是否有效,如果有效則用戶可以訪問受保護(hù)的資源。
如果JWT包含足夠多的必要數(shù)據(jù),那么就可以減少對數(shù)據(jù)庫的某些查詢操作,盡管可能并不是如此。
如果token是在授權(quán)頭(Authorization header)中發(fā)送的,那么跨源資源共享(CORS)將不會成為問題,因?yàn)樗皇褂胏ookie。
基于Token的身份認(rèn)證與基于服務(wù)器的身份認(rèn)證
基于服務(wù)器的身份認(rèn)證
在討論基于Token的身份認(rèn)證是如何工作的以及它的好處之前,我們先來看一下以前我們是怎么做的:
HTTP協(xié)議是無狀態(tài)的,也就是說,如果我們已經(jīng)認(rèn)證了一個(gè)用戶,那么他下一次請求的時(shí)候,服務(wù)器不知道我是誰,我們必須再次認(rèn)證。
傳統(tǒng)的做法是將已經(jīng)認(rèn)證過的用戶信息存儲在服務(wù)器上,比如Session。用戶下次請求的時(shí)候帶著JSessionID,然后服務(wù)器以此檢查用戶是否認(rèn)證過。
這種基于服務(wù)器的身份認(rèn)證方式存在一些問題:
- Sessions:每次用戶認(rèn)證通過以后,服務(wù)器需要創(chuàng)建一條記錄保存用戶信息,通常是在內(nèi)存中,隨著認(rèn)證通過的用戶越來越多,服務(wù)器在這里的開銷就會越來越大。
- Scalability:由于Session是在內(nèi)存中的,這就帶來一些拓展性的問題。
- CORS:當(dāng)我們想要拓展我們的應(yīng)用,讓我們的數(shù)據(jù)被多個(gè)移動設(shè)備使用時(shí),我們必須考慮資源共享問題。當(dāng)時(shí)用異步請求調(diào)用另一個(gè)域名下的資源時(shí),我們可能會遇到禁止請求的問題和Session中保存的用戶數(shù)據(jù)不存在等問題
- CSRF:用戶很容易收到CSRF攻擊。
基于Token的身份認(rèn)證
JWT與Session的差異/相同點(diǎn)是:它們都存儲用戶信息;然而Session是在服務(wù)端的,而JWT是在客戶端的。
Session存儲用戶信息的最大問題在于要占用大量服務(wù)器內(nèi)存,增加服務(wù)器的開銷以及多個(gè)服務(wù)Session資源不共享問題
而JWT方式將用戶狀態(tài)分散到了客戶端中,可以明顯減輕服務(wù)端的內(nèi)存壓力。
Session的狀態(tài)是存儲在服務(wù)端,客戶端只有JSessionId;而Token的狀態(tài)是存儲在客戶端。
基于Token的身份認(rèn)證是如何工作的
基于Token的身份認(rèn)證是無狀態(tài)的,服務(wù)器或者Session中不會存儲任何用戶信息。
沒有會話信息意味著應(yīng)用和層序可以根據(jù)需要拓展和添加更多的機(jī)器,而不必?fù)?dān)心用戶登錄的位置。
雖然這一實(shí)現(xiàn)可能會有所不同,但其主要流程如下:
- 用戶攜帶用戶名和密碼請求訪問
- 服務(wù)器校驗(yàn)用戶憑據(jù)
- 應(yīng)用提供一個(gè)token給客戶端
- 客戶端存儲token
- 并且在隨后的每一次請求中都帶著它
- 服務(wù)器校驗(yàn)token并返回?cái)?shù)據(jù)
注意:
- 每一次請求都需要token
- token應(yīng)該放在請求header中
- 我們還需要將服務(wù)器設(shè)置為接受來自所有域的請求,用Access-Control-Allow-Origin: “*”
用Token的好處
無狀態(tài)和可拓展性
Tokens存儲在客戶端,完全無狀態(tài),可拓展。我們的負(fù)載均衡器可以將用戶傳遞到任意服務(wù)器,因?yàn)樵谌魏蔚胤蕉紱]有狀態(tài)或會話信息。
安全
Token不是Cookie,每次請求的時(shí)候Token都會被發(fā)送。
而且,由于沒有Cookie被發(fā)送,還有助于防止CSRF攻擊。
即使在你的實(shí)現(xiàn)中將token存儲到客戶端的Cookie中,這個(gè)Cookie也只是一種存儲機(jī)制,而非身份認(rèn)證機(jī)制。
沒有基于會話的信息可以操作,因?yàn)槲覀儧]有會話。
還有一個(gè)點(diǎn),token在一段時(shí)間以后會過期,這個(gè)時(shí)候用戶需要重新登錄。這有助于我們保持安全。
還有一個(gè)概念叫token撤銷,它允許我們根據(jù)相同的授權(quán)許可使特定的token甚至一組token無效。
JWT和OAuth的區(qū)別
OAuth2是一種授權(quán)框架,JWT是一種認(rèn)證協(xié)議。
無論使用哪種方式切記用HTTPS保證數(shù)據(jù)的安全性
OAuth2用在使用第三方賬號登錄的情況(比如weibo,qq,github登錄某個(gè)APP)。而JWT使用在前后端分離,需要將簡單的對后臺的API進(jìn)行保護(hù)時(shí)使用。
到此這篇關(guān)于JWT令牌的工作原理詳解的文章就介紹到這了,更多相關(guān)JWT令牌原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決java中mybatis報(bào)錯(cuò):org.apache.ibatis.binding.BindingException:
這篇文章主要介紹了解決java中mybatis報(bào)錯(cuò):org.apache.ibatis.binding.BindingException:Invalid bound statement(not found):xx問題,具有很好的參考價(jià)值,希望對大家有所幫助2024-03-03Spring Cloud Sleuth整合zipkin過程解析
這篇文章主要介紹了Spring Cloud Sleuth整合zipkin過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12springboot?+rabbitmq+redis實(shí)現(xiàn)秒殺示例
本文主要介紹了springboot?+rabbitmq+redis實(shí)現(xiàn)秒殺示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07SpringBoot集成JWT實(shí)現(xiàn)token驗(yàn)證的流程
Json web token (JWT), 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)((RFC 7519).這篇文章主要介紹了SpringBoot集成JWT實(shí)現(xiàn)token驗(yàn)證,需要的朋友可以參考下2020-01-01java文字轉(zhuǎn)語音的實(shí)現(xiàn)示例
在Java中,我們可以使用第三方庫來實(shí)現(xiàn)文字轉(zhuǎn)語音的功能,本文主要介紹了java文字轉(zhuǎn)語音的實(shí)現(xiàn)示例,選擇jacob技術(shù)實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03MyBatis-Plus實(shí)現(xiàn)字段自動填充功能的示例
本文主要介紹了MyBatis-Plus實(shí)現(xiàn)字段自動填充功能的示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11Java批量操作文件系統(tǒng)的實(shí)現(xiàn)示例
文件上傳和下載是java web中常見的操作,本文主要介紹了Java批量操作文件系統(tǒng)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03SpringBoot線程池ThreadPoolTaskExecutor異步處理百萬級數(shù)據(jù)
本文主要介紹了SpringBoot線程池ThreadPoolTaskExecutor異步處理百萬級數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03