系統登入認證流程對比(cookie方式與jwt)
系統登入認證流程對比(cookie方式與jwt)
一個正在努力愛好運動的程式猿
座右銘:越努力越幸運,越運動越健康,熱愛程式設計,熱愛運動。
文章目錄
背景知識:
Authentication和Authorization的區別:
Authentication:使用者認證,指的是驗證使用者的身份,例如你希望以小A的身份登入,那麼應用程式需要通過使用者名稱和密碼確認你真的是小A。
Authorization:授權,指的是確認你的身份之後提供給你許可權,例如使用者小A可以修改資料,而使用者小B只能閱讀資料。
由於http協議是無狀態的,每一次請求都無狀態。當一個使用者通過使用者名稱和密碼登入了之後,他的下一個請求不會攜帶任何狀態,應用程式無法知道他的身份,那就必須重新認證。因此我們希望使用者登入成功之後的每一次http請求,都能夠儲存他的登入狀態。
目前主流的使用者認證方法有基於token和基於session兩種方式。
一、cookie方式登入認證
步驟:
1.使用者向伺服器傳送使用者名稱和密碼。
2.伺服器驗證後,相關資料(如使用者角色等)將儲存在當前會話(session)中。
3.伺服器向使用者返回sessionId會寫入到使用者的Cookie。
4.使用者後續請求都將通過在Cookie中取出sessionId傳給伺服器。
5.伺服器收到sessionId並對比之前儲存的資料,確認使用者的身份。
二、JWT(Json Web Token)方式登入認
JWT(Json Web Token)
資料結構:其中第一段為 header(頭),第二段為 payload (負載),第三段為signature(簽名)
步驟:
1.使用者輸入其登入資訊
2.伺服器驗證資訊是否正確,並返回已簽名的token
3.token儲在客戶端,例如存在local storage或cookie中
4.之後的HTTP請求都將token新增到請求頭裡
5.伺服器解碼JWT,並且如果令牌有效,則接受請求
6.一旦使用者登出,令牌將在客戶端被銷燬,不需要與伺服器進行互動一個關鍵是,令牌是無狀態的。後端伺服器不需要儲存令牌或當前session的記錄。
三、區別優缺點
基於session和基於jwt的方式的主要區別就是使用者的狀態儲存的位置,session是儲存在服務端的,而jwt是儲存在客戶端的。
jwt的優點:
- 可擴充套件性好
應用程式分散式部署的情況下,session需要做多機資料共享,通常可以存在資料庫或者redis裡面。而jwt不需要。
- 無狀態
jwt不在服務端儲存任何狀態。RESTful API的原則之一是無狀態,發出請求時,總會返回帶有引數的響應,不會產生附加影響。使用者的認證狀態引入這種附加影響,這破壞了這一原則。另外jwt的載荷中可以儲存一些常用資訊,用於交換資訊,有效地使用 JWT,可以降低伺服器查詢資料庫的次數。
jwt的缺點:
- 安全性
由於jwt的payload是使用base64編碼的,並沒有加密,因此jwt中不能儲存敏感資料。而session的資訊是存在服務端的,相對來說更安全。
- 效能
jwt太長。由於是無狀態使用JWT,所有的資料都被放到JWT裡,如果還要進行一些資料交換,那載荷會更大,經過編碼之後導致jwt非常長,cookie的限制大小一般是4k,cookie很可能放不下,所以jwt一般放在local storage裡面。並且使用者在系統中的每一次http請求都會把jwt攜帶在Header裡面,http請求的Header可能比Body還要大。而sessionId只是很短的一個字串,因此使用jwt的http請求比使用session的開銷大得多。
- 一次性
無狀態是jwt的特點,但也導致了這個問題,jwt是一次性的。想修改裡面的內容,就必須簽發一個新的jwt。
(1)無法廢棄
通過上面jwt的驗證機制可以看出來,一旦簽發一個jwt,在到期之前就會始終有效,無法中途廢棄。例如你在payload中儲存了一些資訊,當資訊需要更新時,則重新簽發一個jwt,但是由於舊的jwt還沒過期,拿著這個舊的jwt依舊可以登入,那登入後服務端從jwt中拿到的資訊就是過時的。為了解決這個問題,我們就需要在服務端部署額外的邏輯,例如設定一個黑名單,一旦簽發了新的jwt,那麼舊的就加入黑名單(比如存到redis裡面),避免被再次使用。
(2)續簽
如果你使用jwt做會話管理,傳統的cookie續簽方案一般都是框架自帶的,session有效期30分鐘,30分鐘內如果有訪問,有效期被重新整理至30分鐘。一樣的道理,要改變jwt的有效時間,就要簽發新的jwt。最簡單的一種方式是每次請求重新整理jwt,即每個http請求都返回一個新的jwt。這個方法不僅暴力不優雅,而且每次請求都要做jwt的加密解密,會帶來效能問題。另一種方法是在redis中單獨為每個jwt設定過期時間,每次訪問時重新整理jwt的過期時間。
可以看出想要破解jwt一次性的特性,就需要在服務端儲存jwt的狀態。但是引入 redis 之後,就把無狀態的jwt硬生生變成了有狀態了,違背了jwt的初衷。而且這個方案和session都差不多了。
總結:
適合使用jwt的場景:
1.有效期短
2.只希望被使用一次
比如,使用者註冊後發一封郵件讓其啟用賬戶,通常郵件中需要有一個連結,這個連結需要具備以下的特性:能夠標識使用者,該連結具有時效性(通常只允許幾小時之內啟用),不能被篡改以啟用其他可能的賬戶,一次性的。這種場景就適合使用jwt。
而由於jwt具有一次性的特性。單點登入和會話管理非常不適合用jwt,如果在服務端部署額外的邏輯儲存jwt的狀態,那還不如使用session。基於session有很多成熟的框架可以開箱即用,但是用jwt還要自己實現邏輯。
轉載於:https://www.cnblogs.com/yuanrw/p/10089796.html
相關文章
- JWT登入認證-專案BotBattleJWTBAT
- JWT實現登入認證例項JWT
- 實戰模擬│JWT 登入認證JWT
- 認證系統之登入認證系統的進階使用 (二)
- 一文搞懂Session和JWT登入認證SessionJWT
- 【連線】禁止以作業系統認證方式登入資料庫作業系統資料庫
- 『JWT』,你必須瞭解的認證登入方案JWT
- 【登陸認證】oracle的作業系統認證和口令檔案認證方式(轉載)Oracle作業系統
- 作業系統認證與ORACLE密碼檔案認證方式作業系統Oracle密碼
- 憑證管理揭秘:Cookie-Session 與 JWT 方案的對決CookieSessionJWT
- oracle登陸認證方式Oracle
- 建站篇-使用者認證系統-自定義登入系統
- 【Python】Django--認證系統-登入註冊PythonDjango
- Ubuntu部署Maxkey單點登入認證系統Ubuntu
- 登入模組 使用者認證 SpringSecurity +Oauth2+JwtSpringGseOAuthJWT
- express實現JWT使用者認證系統ExpressJWT
- 在windows透過作業系統認證登入ORACLEWindows作業系統Oracle
- 在windows通過作業系統認證登入ORACLEWindows作業系統Oracle
- drf JWT認證模組與自定製JWT
- 淺談 Cookie-Session 、Jwt 兩種身份認證機制CookieSessionJWT
- JWT 多表認證JWT
- QQ第三方登入認證流程(乾貨)
- Spring Boot + Security + JWT 實現Token驗證+多Provider——登入系統Spring BootJWTIDE
- oracle兩種登陸認證方式Oracle
- URL載入系統之四:認證與TLS鏈驗證TLS
- 直播系統程式碼,登入時常用驗證方式實現
- JWT技術解決IM系統的認證痛點JWT
- MySQL登入驗證方式MySql
- 瞭解JWT認證JWT
- drf的JWT認證JWT
- DRF JWT認證(一)JWT
- DRF JWT認證(二)JWT
- DRF之JWT認證JWT
- 圖解Jwt和shiro認證方式的區別圖解JWT
- cookie之登入使用者憑證Cookie
- golang 中使用 JWT 實現登入驗證GolangJWT
- Flask Session 登入認證模組FlaskSession
- passport API 認證 -- 多表登入PassportAPI