NodeJS Koa 后端用戶會話管理,JWT, Session,長短Token,本文一次性講明白

前言

前幾天,我寫了一篇文章,《我設計的一個安全的 web 系統用戶密碼管理流程》。其中著重點是講的如何利用非對稱加密進行安全的設計,并在講述了原理之后,又寫了 《node 后端和瀏覽器前端,有關 RSA 非對稱加密的完整實踐, 前后端匹配的代碼演示》 這篇文章,著重講解了有關 RSA 非對稱加密的完整實現。

但是,這些文章里并沒有講到用戶登錄管理的核心,也就是用戶會話管理。這里面有很多概念,對于很多前端開發和很多初級后端開發來說,都是很模糊的。所以,今天,我想通過這一篇文章,把這里面的核心點全部講明白。

基礎概念

我們會聽到一些詞,大概是 SessionSession IDCookiesToken 等等,現在又有了新詞兒,新的解決方案,如 JWT,長短 Token 等等。

我們一個一個來講。這些詞分別有對應的英文意思,但是每個詞都有多個含義,并且在不同的環境下,還會有衍生不同的含義。因此,我這邊只能從前后端開發的角度去解釋這些名詞,不能按照字典的含義去解釋。

而且,由于網上言論眾多,其中謬誤的也好,佶屈聱牙的也罷,我都不去管它,我只按照我的理解來講解,并且,我相信,我的理解是非常深入到位的。

Session

翻譯——會話,引申為會話管理。那么,什么是會話呢?

首先,我們要理解一個基礎概念——http 服務,是一種無狀態服務。怎么理解無狀態呢?一句話講,就是——在默認情況下,后端程序根本不知道前端發過來的請求,誰是誰!

為了解決這個不知道誰是誰的問題,就引申出來解決方案——讓后端程序知道,每一個請求,都是誰發出來的,好相應的把對應的資源發回去。

比如,張三請求 profile 接口,返回的內容應該 {name:"張三"},而不能是 {name:“李四”}。

那么,我們就可以理解,張三發出來的一系列的請求,應該歸屬于一個會話,李四發出來的一系列請求,應該歸屬于另一個會話。

所以,我們就需要把這一系列的會話,進行管理,這就是會話管理

換句話想,Session,并不是一個單純的詞,而是一個相對很大的概念,為了解決這個問題,不同的語言有不同的解決方案,這些各種不同的解決方案,都可以統稱為 Session。

Session ID

理解了上面的 Session 的概念,這個概念就相對比較好理解了。每一個用戶,都有一堆的資源,我們不能把這些資源都隨時在程序里放著。因此,我們會把這些資源打包存著,然后整出一個 ID 來,方便我們來查詢。這樣,前端只要給我們這個 ID,我們就可以根據這個ID查找到對應的資源。

這里說的用戶資源,是指 用戶名,用戶昵稱,用戶角色,過期時間等簡短信息,只要方便后端程序快速的分清楚這貨是誰,能干些啥事兒即可。不是說,要把所有的用戶資源信息,全部存著。如果是那樣的話,還要數據庫干啥呢對吧。

Token

字面意思,憑證,令牌。是后端下發給前端的一段字符串(可長可短,你要愿意,給數字也不是不行,看你咋設計了。)

前端拿到這個 Token 以后,它每次發起請求時,都需要把這個 Token 給帶上,后端根據這個 Token ,就可以去查找對應的資源了。

OK,注意到了嗎?上面的 Session ID 是方便我們后端去查找資源的,這個 Token,也是后端去查找對應資源的。

所以—— Token = Session ID ?

答案是不一定。要看你咋設計。

一般而言,我是傾向于設計為 Token,就是 Session ID。當然,也可以不一樣,前端給后端 Token,后端先根據 Token 去查找 SessionID,然后根據 ID 再查找對應資源,也是可以的對吧?

但我感覺這樣設計有點缺心眼兒。

Cookies

字面意思是一種餅干,我不喜歡吃餅干,所以我不知道它具體是哪一種餅干。

Cookies 是用戶瀏覽器的一種機制,它可以由我們的后端程序去設定。而且,在每次用戶發起請求的時候,瀏覽器都會把 Cookies 自動帶上。

換句話講,如果我們使用 Cookies,可以大幅的減少前端開發的工作量,因為具體是咋實現的,不用管了,瀏覽器自動實現。

但問題是,現在的前端開發,往往不僅僅是運行在瀏覽器里面的網頁,還有 APP、 小程序或者其他客戶端程序,而這些里面,大多是沒有 Cookies 的機制的。

因此,為了我們的后端服務可以同時服務多端,我建議就不要管這個玩意兒了。

不是不能用,順手的時候,也可以兼容。

JWT

JSONWebToken 的縮寫。在傳統的會話管理里,都涉及一個存儲的問題,就是,要把用戶資源存著,然后去查詢。你可以存在內存里,文件里,數據庫里,等等,總之,你要存數據,并且方便查詢。

JWT

假設,我們存在內存里,而我們的后端服務運行在多臺負載均衡的服務器上,那么,當用戶的 A 請求訪問在甲服務器上,甲服務器在內存里存儲了數據,B請求訪問在乙服務器上,而乙服務器的內存中并沒有用戶數據,則會出現讀取失敗的問題。

怎么解決呢?聰明的你一定想到了解決方案——集中存儲,比如單獨搞一臺 redis 服務器,大家都往這里存。挺好的。

那么假設你的這些服務器不在一個機房呢?也不是不能讀是吧,就是慢點兒。

總之,傳統的會話管理,有一個問題,就是 IO 問題,也就是存儲和讀取的問題。

JWT 方案是換了一個思路來解決,其核心原理是,直接將用戶的資源信息加密,然后返回給客戶端,客戶端拿這個加密的長字符串直接作為 Token 來請求,后端程序只要解密字符串,就直接獲得了用戶的資源信息了。

也就是說, JWT 是用計算復雜度取代了存儲復雜度,來解決上面說的問題。

總之,會話管理是一定要消耗資源的,要么是存儲復雜度,要么是計算復雜度。


在很多文章和概念里,把 JWT 方案,和 Session 方案并列對比。可以這么比,但是我感覺概念不對。其實在我看來,JWT 方案,只是一種 Session 解決方案而已,兩者是上下級的關系,而不是并列的關系。

我這邊把傳統的通過存儲(你別管存哪兒,咋存)解決方案,稱之為傳統存儲方案吧。

和傳統存儲方案相對比,優缺點如下

特點JWT存儲
服務器狀態無狀態有狀態
跨域支持天然支持需CORS配置
實時吊銷默認不支持支持
傳輸效率大點兒,問題不大小,可忽略

其實總結下來,JWT最大的問題就是,一旦 Token 簽發,除了超時失效,否則是沒辦法把用戶登出的。

當然,聰明的你,肯定想到了黑名單機制,把登出的 Token 存下來,然后每次讀取驗證一下。那么我的問題是,那你為啥不用傳統的存儲會話管理,要用 JWT ?吃飽撐的?

長短 Token

好,通過上面的這些概念,我們知道,JWT 方案,不方便管理用戶,傳統存儲解決方案,有IO性能問題,那么能不能兩種方案結合結合,咱們取長補短!

可以,于是,有了長短 Token 的解決方案。

每次用戶登錄時,用 JWT 方式,簽發一個長的 Token,這個 Token 的過期時間比較短,比如5分鐘。5分鐘后,它就失效了。

同時,用傳統存儲方案,簽一個短的 Token。這個過期時間可以設置得比較長,比如一個月。

在正常業務時,后端直接讀取用戶傳過來的 JWT 信息,就可以得到用戶資源了。當前端發現 token 過期了,就拿 短 token 過來,再請求一個長 token,然后再繼續使用。

這樣,就解決了存儲問題,又可以管理用戶登出(直接在存儲里刪掉用戶的短Token 即可)

代價是什么呢?代價是提高了各個前端項目的代碼復雜度。你可以說,長短 Token 的解決方案是集合了兩種解決方案的長處,也可以理解為,兩者的短處也全粘上了。

傳輸數據變大,還是得存儲用戶信息,還消耗CPU計算資源等等。

小結

綜上所述,我們應該對用戶會話管理這塊的概念都有了一個清晰的理解了。那么我們在開發項目時應該如何選擇呢?

首先,無論是哪種解決方案,你都得會!沒有什么方案是一招鮮,吃遍天的。

例如,傳統存儲方案中的所謂 IO 問題,對于絕大多數項目來說,這就是一個不存在的問題。直接往內存一存,有啥性能瓶頸?攏共就跑在一臺服務器上,哪里來的什么速度或者進程共享的問題?在我看來,絕大多數項目,連 redis 都是多余。

再說,JWT 方案,有啥登出管理問題?一個小系統,一天登錄攏共就幾個人,你設置為有效期1天,我也不認為有多大的安全隱患,如果真遇到了什么大問題,直接把 JWT 的簽發加密詞一改,所有簽發的TOKEN,全部失效。

最后說說長短 TOKEN,如果你團隊有足夠多的人手,項目也確實有很高的安全性,可以考慮使用。否則,是徒增麻煩。

所以,我推薦你根據你自己的項目選擇合適的解決方案,我只說我的觀點:

  1. 大多數項目都可以使用 JWT 方案。
  2. 你有切實的要迫使用戶登出的項目,比如論壇等等,可以用傳統的存儲方案。
  3. 你團隊實力足夠,甲方是安全潔癖,項目也確實有高等級的要求,或者產品或老板想裝逼忽悠客戶,長短TOKEN你值得擁有!

本來,我是想在這篇文章中,引用一些代碼,方便各位看官理解的,沒想到,光講概念就講了這么多了。沒辦法,周末抽空,我會把每種方案的 NodeJS + Koa 的實戰完整代碼給寫成文章分享給大家。


最近我在參加 CSDN 的一個創作比賽,各位看官在留言區留言可以給我加分。所以希望各位看官幫幫忙,點評一下哦!

當然,我們程序開發都是很忙滴,沒時間點評沒關系哈,點個贊,收個藏,也不是不可以哈!耽誤不了您的事兒,還能讓我繼續保持創作熱情,小可在這邊謝謝各位看官了哈!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908412.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908412.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908412.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

0.5S 級精度背后:DJSF1352-RN-6 如何讓儲能電站的每 1kWh 都「有跡可循」?

1、背景 在能源轉型的時代洪流里,大型儲能電站作為保障電網穩定運行、平衡能源供需的核心基礎設施,其戰略價值愈發凸顯。而儲能電站的高效運轉,始終離不開精準的電能計量體系支撐。今日為您重點推介一款針對 1500V 儲能系統研發的專業電能表…

Linux運維筆記:服務器安全加固

文章目錄 背景加固措施1. 修改用戶密碼2. 使用公鑰認證替代密碼登錄3. 強化系統安全4. 掃描與清理殘留威脅5. 規范軟件管理(重點) 注意事項總結 提示:本文總結了大學實驗室 Linux 電腦感染挖礦病毒后的安全加固措施,重點介紹用戶密…

Pycharm 配置解釋器

今天更新了一版pycharm,因為很久沒有配置解釋器了,發現一直失敗。經過來回試了幾次終于成功了,記錄一下過程。 Step 1 Step 2 這里第二步一定要注意類型要選擇python 而不是conda。 雖然我的解釋器是conda 里面建立的一個環境。挺有意思的

【Linux】awk 命令詳解及使用示例:結構化文本數據處理工具

【Linux】awk 命令詳解及使用示例:結構化文本數據處理工具 引言 awk 是一種強大的文本處理工具和編程語言,專為處理結構化文本數據而設計。它的名稱來源于其三位創始人的姓氏首字母:Alfred Aho、Peter Weinberger 和 Brian Kernighan。 基…

MS1023/MS1224——10MHz 到 80MHz、10:1 LVDS 并串轉換器(串化器)/串并轉換器(解串器)

產品簡述 MS1023 串化器和 MS1224 解串器是一對 10bit 并串 / 串并轉 換芯片,用于在 LVDS 差分底板上傳輸和接收 10MHz 至 80MHz 的并行字速率的串行數據。起始 / 停止位加載后,轉換為負載編 碼輸出,串行數據速率介于 120Mbps…

跟我學c++中級篇——理解類型推導和C++不同版本的支持

一、類型推導 在前面反復分析過類型推導(包括前面提到的類模板參數推導CTAD),類型推導其實就是滿足C語言這種強類型語言的要求即編譯期必須確定對象的數據類型。換一句話說,理論上如果編譯器中能夠自動推導所有的相關數據類型&am…

vue3+TS+eslint9配置

記錄eslint升級到9.x的版本之后遇到的坑 在 ESLint 9 中,配置方式發生了變化。Flat Config 格式(eslint.config.js 或 .ts)不再支持 extensions 選項。所以vscode編輯器中的 extensions 需要注釋掉,要不然保存的時候不會格式化。…

書籍推薦 --- 《篳路維艱:中國經濟社會主義路徑的五次選擇》

蕭冬連.篳路維艱:中國社會主義路徑的五次選擇[M]. 前不久看完的這本書,還是蠻受震撼的。 這本書比較細致地(引用了很多的史料)、從中央高層的視角講解了從新中國成立一直到改革開放初期這30多年里(1949---1980年代)發生在我國的幾次重大事件(三大改造、第一個五年計…

C++課設:簡易日歷程序(支持傳統節假日 + 二十四節氣 + 個人紀念日管理)

名人說:路漫漫其修遠兮,吾將上下而求索。—— 屈原《離騷》 創作者:Code_流蘇(CSDN)(一個喜歡古詩詞和編程的Coder😊) 專欄介紹:《編程項目實戰》 目錄 一、為什么要開發一個日歷程序&#xff…

(三)動手學線性神經網絡:從數學原理到代碼實現

1 線性回歸 線性回歸是一種基本的預測模型,用于根據輸入特征預測連續的輸出值。它是機器學習和深度學習中最簡單的模型之一,但卻是理解更復雜模型的基礎。 1.1 線性回歸的基本元素 概念理解: 線性回歸假設輸入特征和輸出之間存在線性關系。…

二十五、面向對象底層邏輯-SpringMVC九大組件之HandlerMapping接口設計

一、引言:MVC架構的交通樞紐 在Spring MVC框架中,HandlerMapping接口扮演著"請求導航儀"的關鍵角色,它決定了HTTP請求如何被路由到對應的Controller處理器。作為MVC模式的核心組件之一,HandlerMapping在請求處理的生命…

凌晨四點的星光

凌晨四點的城市像臺停止運轉的老舊機器,陳明裹緊外套踩著路燈的殘影往家走。鍵盤敲擊聲仿佛還在耳邊回響,他揉了揉酸澀的眼睛,手機屏幕突然亮起,是妻子發來的消息:“孩子又發燒了,我帶他去醫院。” 這是他…

Kyosan K5BMC ELECTRONIC INTERLOCKING MANUAL 電子聯鎖

Kyosan K5BMC ELECTRONIC INTERLOCKING MANUAL 電子聯鎖

LeetCode 熱題 100 74. 搜索二維矩陣

LeetCode 熱題 100 | 74. 搜索二維矩陣 大家好,今天我們來解決一道經典的算法題——搜索二維矩陣。這道題在 LeetCode 上被標記為中等難度,要求我們在一個滿足特定條件的二維矩陣中查找一個目標值。如果目標值在矩陣中,返回 true&#xff1b…

如何在 HTML 中添加按鈕

原文:如何在 HTML 中添加按鈕 | w3cschool筆記 (請勿將文章標記為付費!!!!) 在網頁開發中,按鈕是用戶界面中不可或缺的元素之一。無論是用于提交表單、觸發動作還是導航&#xff0…

一篇文章實現Android圖片拼接并保存至相冊

系列文章目錄 一篇文章實現Android圖片拼接并保存至相冊 文章目錄 系列文章目錄前言實現功能類定義和成員變量onCreate方法權限檢查和圖片選擇處理選擇的圖片圖片拼接功能圖片保存功能 使用ImageStitcher類拼接圖片代碼解釋:ImageStitcher.java類定義和方法計算拼接…

2025.06.06【Ribo-seq】|riboWaltz:P-site定位與三堿基周期性分析流程

文章目錄 一、前言二、riboWaltz簡介三、安裝與依賴四、分析流程總覽1. 數據準備2. 典型分析流程2.1 讀取注釋和BAM2.2 P-site定位2.3 三堿基周期性與元分析2.4 密碼子使用偏好分析 五、可視化與結果解讀六、常見問題與注意事項七、實戰經驗與建議八、參考資料九、結語 一、前言…

思維鏈的 內部機制和簡單理解

思維鏈的 內部機制和簡單理解 思維鏈是對解決問題的步驟進行規劃,規劃后將作為上下文 在LLM中繼續輸出。因為Transform都是一個一個單詞生成,沒新生成一個單詞都會將新生的作為上下文。 可以這么理解,但更準確的簡化描述是: 思維鏈是讓模型在回答問題時,先“內部生成”或…

Charles 全流程指南:安裝、設置、抓包與注意事項

Charles 是一款功能強大的網絡抓包工具,支持 HTTP/HTTPS 流量監控、請求/響應分析、斷點調試等功能。本文將從安裝到實戰抓包,提供完整流程及關鍵注意事項。 一、安裝 Charles 官網下載:訪問 Charles 官網,選擇對應系統版本&…

全球長序列高分辨率光合有效輻射(PAR)(1984-2018)

時間分辨率:時空間分辨率:1km - 10km共享方式:開放獲取數據大小:188.92 GB數據時間范圍:1984-01-01 — 2018-12-31元數據更新時間:2022-04-29 數據集摘要 本數據集是一個包含接近35年(1984-201…