目前絕大多數的系統都少不了登入驗證的功能,這主要是為了保存使用者的狀態,以此來限制使用者的各種行為,從而方便有效的控制用戶的權限。例如一個使用者登陸微博,發布、追蹤、評論的操作都應是在登入後的使用者狀態下進行的。
實作登入驗證的功能主要有Cookie&Session
、JWT
兩種方式,這一節我們將先對Cookie&Session
的工作原理 做詳細的介紹,在之後的文章中會陸續對JWT
,以及如何使用Cookie&Session
和JWT
來完善前幾節我們建置的簡易用戶管理系統進行講解。 【相關教學推薦:nodejs影片教學】
1️⃣ Cookie&Session
我們知道,HTTP 是無狀態的。也就是說,HTTP 請求方和回應方間無法維護狀態,都是一次性的,它不知道前後的請求都發生了什麼事。但有的場景下,我們需要維護狀態。最典型的,一個使用者登陸微博,發佈、追蹤、評論,都應是在登入後的使用者狀態下的。
這個時候就可以引入Cookie
與Session
來儲存使用者的登入狀態。
本篇文章主要介紹使用
Cookie-Session
來做登入驗證的工作原理,關於Cookie
#與Session
的詳細介紹可查閱這位大佬的文章:Cookie和Session詳解
為什麼不單獨使用Cookie?
Cookie
是存放在瀏覽器中的,可以在瀏覽器中開啟控制台
,選擇應用程式
,找到儲存
中的Cookie
進行檢視:
#當客戶端向服務端發送網路請求時瀏覽器會自動將Cookie
加入到請求頭中,這樣服務端就能取得這個Cookie
,如下:
知道了這個原理後,我們就可以想到,如果在使用者登入系統時:客戶端由使用者的部分登入資訊(例如username
、id
等)產生一個Cookie
存放到瀏覽器中,那麼在這之後的每一次網路請求都會自動攜帶上該Cookie
。
之後讓服務端根據請求中是否攜帶Cookie
並且攜帶的Cookie
中是否存在有效的username
、id
來判斷使用者是否已經登入過了,這樣一來使用者的登入狀態不就被保存下來了嗎。
回到上面我們提到的微博的例子,按照這個過程來說,當使用者登入後Cookie
已經被儲存,這時當使用者進行發佈、追蹤、評論等需要登入才能使用的操作時我們就能提前判斷是否存在Cookie
,如果存在且Cookie
中含有該使用者的id
,那麼我們就可以允許該使用者的這些操作(這些操作一般都是需要使用者的id
的,這時就可以從Cookie
中進行取得)。相反的,如果Cookie
不存在或Cookie
#無效,那麼就禁止該使用者的這些操作。
說到這,你可能會問:既然一個Cookie
就能實現我們想要的效果,那為何還要使用Session
呢?
這是因為 Cookie
很容易被偽造! ,如果我們知道了Cookie
中存放的資訊是username
和id
(就算不知道,也可以登入後的網路請求的請求體中找到Cookie
),那麼我們完全可以在不登入的情況下手動向瀏覽器儲存一個偽造的Cookie
:
說到這,你應該就能明白為什麼不能單獨使用Cookie
了吧。
Session是如何與Cookie結合的?
Session
其實是基於Cookie
實現的,並且Session
儲存在服務端的記憶體或資料庫中。
當使用者登入成功時,使用Cookie&Session
的登入驗證會進行以下操作:
-
由服務端產生
Session
與SessionId
;Session
一般是根據使用者登入的信息,如使用者名稱、id
等進行生成。
如果把Session
比喻為是一把鎖,那麼SessionId
就等於是這把鎖的鑰匙。 服務端將
Session
儲存到記憶體或資料庫中;服務端將
SessionId
存放到請求的回應頭(response
物件)中的Set-Cookie
欄位中傳送給客戶端;客戶端收到
Set-Cookie
後會自動將Set-Cookie
的值(也就是SessionId
)存放到Cookie
中;之後的每個網路請求都會自動帶上
Cookie
,也就是帶上這個SessionId
;服務端收到後續請求時取得請求上的
Cookie
,也就是取得到了SessionId
,然後透過SessionId
#查詢並校驗服務端儲存的Session
,若校驗成功說明這個SessionId
有效則透過此請求,反之則阻止此請求。
圖示:
#2️⃣ Cookie&Session的缺陷
# 儲存問題
為了保存使用者的登入狀態,我們需要為每位登入的使用者產生並儲存Session
,這勢必就會造成以下問題:
- 如果
Session
存放到記憶體中,那麼當服務端重啟時,這些記憶體中的Session
都會被清除,那麼所有使用者的登入狀態都會過期,當使用者量較大時,過多的記憶體佔用也勢必會影響服務端的效能。 - 如果
Session
存放到資料庫中,雖然能夠解決因服務端重啟造成用戶登入狀態過期的問題,但當用戶量較大時,對於這個資料庫的維護也會改變得相對困難。 - 如果前端頁面中呼叫的介面來自兩個伺服器(也就是兩套資料庫),為了實作
Session
在兩個伺服器間共用通常會將Session
存放到一個單獨的資料庫中,這樣就使得整個專案變得更為複雜也更難維護。
CSRF問題
CSRF 全稱為Cross-site request forgery 即跨站請求偽造,使用Cookie
進行驗證的網站都會面臨或大或小的CSRF
威脅,我們以一個銀行網站的例子來介紹CSRF的攻擊原則:
假如一家銀行網站A
的登入驗證採用的是Cookie&Session
,並且該網站上用以執行轉帳作業的Api位址
為:http://www.grillbankapi.com/?account=AccoutName&amount=1000
api
參數:account
代表帳戶名,amount
代表轉帳金額。
那麼,一個惡意攻擊者可以在另一個網站B
上放置以下程式碼:
<img src="/static/imghwm/default1.png" data-src="http://www.grillbankapi.com/?account=Ailjx&amount=1000" class="lazy" alt="Node學習之聊Cookie-Session登入驗證的工作原理" >
注意:
img
標籤的src
是網站A
轉帳操作的api位址
,且參數account
為Ailjx,amount
為1000 ,也就是說這個api位址
相當於是帳戶名稱名為Ailjx 轉帳1000 時調用的api
。
如果有帳號名稱Ailjx 的使用者剛造訪過網站A
不久,登入資訊尚未過期(網站A
的Cookie
存在且有效)。
那麼當Ailjx 訪問了這個惡意網站B
時,上面的img
標籤將被加載,瀏覽器就會自動請求img
標籤的src
路由,也就是請求http://www.grillbankapi.com/?account=Ailjx&amount=1000
(我們將這個請求記為請求Q
),並且因為Cookie
存放在瀏覽器中且瀏覽器發送請求時會自動帶上Cookie
,所以請求Q
上就會自動攜帶Ailjx 在網站A
上的Cookie
憑證,結果就是這個請求Q
將會被通過,那麼Ailjx 就會損失1000資金。
這種惡意的網址可以有很多種形式,藏身於網頁中的許多地方。 此外,攻擊者也不需要控制放置惡意網址的網站。例如他可以將這種地址藏在論壇,部落格等任何用戶生成內容的網站中。這意味著如果服務端沒有合適的防禦措施的話,使用者即使訪問熟悉的可信任網站也有受攻擊的危險。
透過例子能夠看出,攻擊者並不能透過CSRF攻擊來直接取得使用者的帳戶控制權,也無法直接竊取使用者的任何資訊。他們能做到的,是欺騙用戶瀏覽器,讓其以用戶的名義運行操作。
這些就是使用Cookie&Session
來做登入驗證的問題所在,那麼我們要如何解決這些問題呢?這就需要引進JWT的概念,使用token
來做登入驗證,這些我們將在之後的文章中進行解說。
更多node相關知識,請造訪:nodejs 教學!
以上是Node學習之聊Cookie-Session登入驗證的工作原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

Atom編輯器mac版下載
最受歡迎的的開源編輯器

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)