主頁 > 後端開發 > 跨越HTTP無狀態邊界:Cookie與Session在Django中的實戰應用

跨越HTTP無狀態邊界:Cookie與Session在Django中的實戰應用

2023-07-12 07:54:00 後端開發

本文深入探索了Django中的Cookie和Session,決議了如何應對HTTP協議的無狀態性問題,說明其基礎概念,分析作業原理,并討論何時應選擇使用Cookie或Session,文章進階部分,提出高效管理Cookie和Session,以及如何利用它們進行用戶身份驗證,

HTTP協議的無狀態性

HTTP,即超文本傳輸協議,是一種應用層協議,它是互聯網上應用最為廣泛的一種網路協議,HTTP協議是無狀態的,但是我們為什么要談論這個無狀態性呢?這個無狀態性又會帶來哪些問題呢?讓我們一起深入探討,

HTTP協議的基本介紹

HTTP是互聯網上應用最為廣泛的一種網路協議,所有的www檔案都必須遵守這個標準,

# 一個典型的HTTP請求
GET /index.html HTTP/1.1
Host: www.example.com

在這個請求中,GET是HTTP的方法,/index.html是要獲取的資源,HTTP/1.1是協議版本,Host是一個HTTP頭,表示請求的域,

什么是無狀態性

HTTP協議是無狀態的,意味著服務器不會記住用戶的資訊,具體來說,當你瀏覽一個網頁,然后跳轉到同一網站的另一個網頁,服務器并不知道這兩個請求來自同一個用戶,

# 第一個HTTP請求
GET /index.html HTTP/1.1
Host: www.example.com

# 第二個HTTP請求
GET /about.html HTTP/1.1
Host: www.example.com

在這個例子中,服務器不會知道/index.html/about.html的請求來自同一個用戶,

無狀態性帶來的問題

HTTP協議的無狀態性意味著每當客戶端獲取服務器資源時,服務器都無法從前一個請求中獲取任何資訊,這就造成了在多頁面、多次請求的Web應用中,資料無法在不同的頁面之間進行共享,

# 用戶在購物車中添加了一件商品
POST /cart/add HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

product_id=1&quantity=1

# 用戶嘗試檢查購物車
GET /cart HTTP/1.1
Host: www.example.com

在這個例子中,由于HTTP的無狀態性,即使用戶在第一個請求中添加了一件商品到購物車,服務器也無法在第二個請求中記住這個操作,用戶查看購物車時可能會發現它是空的,這顯然是不符合我們的預期的,

Cookie與Session的基本概念

為了解決HTTP協議無狀態性帶來的問題,Web應用通常使用Cookie和Session來在用戶的多個請求之間保存狀態,接下來,讓我們深入探討這兩種技術,

什么是Cookie

Cookie是服務器發送到用戶瀏覽器并保存在瀏覽器上的一塊資料,它會在瀏覽器下一次向同一服務器發出請求時被攜帶并發送到服務器上,

# 服務器在回應頭中設定Cookie
HTTP/1.1 200 OK
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2023 07:28:00 GMT;

# 瀏覽器下一次請求攜帶這個Cookie
GET /index.html HTTP/1.1
Host: www.example.com
Cookie: id=a3fWa;

什么是Session

Session是另一種在用戶的多個請求間保持狀態的方式,它更像是在服務器端保存的一個資料結構,可以保存用戶在服務器上的操作記錄,

# 用戶登錄,服務器創建一個Session,并將Session ID發送給瀏覽器
POST /login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

username=john&password=123456

# 服務器回應
HTTP/1.1 200 OK
Set-Cookie: sessionid=123abc; 

# 用戶訪問受保護的資源,瀏覽器發送包含Session ID的請求
GET /dashboard HTTP/1.1
Host: www.example.com
Cookie: sessionid=123abc;

Cookie與Session的作用和區別

  • Cookie和Session都是為了解決HTTP協議的無狀態性而生的,它們都可以在用戶的多個請求間保持狀態,
  • Cookie資料存放在客戶的瀏覽器上,Session資料放在服務器上,
  • 從安全性來講,Session會比Cookie更安全,因為Cookie的資訊可以在瀏覽器端被篡改,而Session存盤在服務器端,客戶端無法修改,
  • 從存盤視角看,Cookie不是非常的"輕量",每次http請求都會攜帶Cookie去服務器,如果使用的Cookie過多,對服務器的性能會有影響,而Session則相對較輕,但如果訪問量過大,會對服務器造成壓力,
  • 常見的做法是使用Cookie來存盤Session id,這樣既解決了存盤空間的問題,又能夠較好地保持狀態,

深入理解Cookie

接下來我們會更詳細地探討一下Cookie,包括其作業原理、屬性以及如何在Python和Django中使用Cookie,

Cookie的作業原理

當用戶首次訪問網站時,服務器通過Set-Cookie HTTP回應頭將Cookie發送到用戶的瀏覽器,瀏覽器將Cookie保存,然后在以后的每次請求中都會通過Cookie HTTP請求頭將Cookie發送回服務器,

Cookie的屬性

一個Cookie有以下幾個主要的屬性:

  • 名稱:一個唯一確定Cookie的名稱,
  • 值:存盤在Cookie中的字串值,
  • 過期時間:定義Cookie何時失效的日期和時間,
  • 路徑:定義哪些網頁可以獲取Cookie,
  • 域:定義哪些網站可以獲取Cookie,
  • Secure:指定Cookie是否只能通過HTTPS傳輸,
  • HttpOnly:指定Cookie是否可以通過JavaScript訪問,

在Python和Django中使用Cookie

在Python和Django中,我們可以很容易地設定和獲取Cookie,

# 在Django中設定Cookie
def set_cookie(request):
    response = HttpResponse("Setting a cookie")
    response.set_cookie('cookie_name', 'cookie_value')
    return response

# 在Django中獲取Cookie
def get_cookie(request):
    value = https://www.cnblogs.com/xfuture/archive/2023/07/11/request.COOKIES.get('cookie_name')
    return HttpResponse(f"The value of cookie 'cookie_name' is {value}")

Cookie的安全性

雖然Cookie在Web應用中非常有用,但是它們也帶來了一些安全問題,例如,如果不當地使用Cookie,攻擊者可能會通過各種方法竊取用戶的Cookie,從而獲取用戶的私人資訊,因此,在使用Cookie時,我們必須始終考慮到安全性,

如何保護你的Cookie

有許多方法可以保護你的Cookie,包括設定Secure和HttpOnly標志,使用同源策略,以及定期更新和洗掉不再需要的Cookie,

深入理解Session

在我們深入研究Session之前,首先需要理解HTTP是無狀態的,每個請求都是獨立的,不知道前一個請求做了什么,這在與用戶互動的Web應用中可能會引發問題,尤其是當我們需要跨多個請求維持狀態時,這就是Session發揮作用的地方,

Session的作業原理

當用戶首次請求網站時,服務器將創建一個新的Session,然后將唯一的Session ID設定為Cookie的一部分,并發送回瀏覽器,然后,當瀏覽器再次向服務器發送請求時,它將包含此Session ID,服務器可以使用它來查找和加載Session,

Session的生命周期

Session的生命周期通常從用戶首次訪問網站開始,直到用戶結束Session,例如通過注銷或關閉瀏覽器,在這個程序中,服務器會一直維護這個Session,如果用戶在一段時間內沒有活動,服務器可能會自動結束Session,以釋放資源,

在Python和Django中使用Session

在Python和Django中,我們可以非常方便地設定和獲取Session,

# 在Django中設定Session
def set_session(request):
    request.session['key'] = 'value'
    return HttpResponse("Setting a session")

# 在Django中獲取Session
def get_session(request):
    value = https://www.cnblogs.com/xfuture/archive/2023/07/11/request.session.get('key')
    return HttpResponse(f"The value of session key is {value}")

Session的安全性

雖然Session在Web應用中非常有用,但是它們也帶來了一些安全問題,例如,如果攻擊者能夠竊取用戶的Session ID,他們就可以冒充用戶,這被稱為Session劫持,因此,在使用Session時,我們必須始終考慮到安全性,

如何保護你的Session

有許多方法可以保護你的Session,包括:使用安全的Cookie來傳輸Session ID,定期重新生成Session ID,對所有敏感操作使用CSRF令牌,定期結束舊的Session等,

Cookie與Session的選擇

在許多情況下,選擇使用Cookie還是Session主要取決于你的特定需求,以下是一些決定使用Cookie還是Session的常見因素,

資料存盤位置

  • 如果你希望資料存盤在客戶端,那么Cookie可能是一個更好的選擇,由于Cookie直接存盤在用戶的瀏覽器上,你的應用可以無需進行服務器端查找就能訪問這些資料,但是,由于Cookie容易被用戶查看和修改,因此不應在Cookie中存盤敏感資訊,
  • 另一方面,如果你的應用需要存盤大量資料,或者你不希望(或不能)將所有資料都存盤在用戶的瀏覽器上,那么你應該選擇使用Session,

安全性

  • 如果你需要存盤敏感資訊,如用戶憑證或支付資訊,那么你應該選擇使用Session,由于Session資料存盤在服務器上,因此它們比存盤在客戶端的Cookie更安全,
  • 然而,你也需要注意Session劫持和Session固定攻擊,這是使用Session時可能遇到的兩種常見安全威脅,你可以通過定期改變Session ID和使用安全的Cookie來減輕這些威脅,

生命周期

  • 如果你需要在用戶關閉瀏覽器后仍然保存資料,那么你應該選擇使用Cookie,你可以設定Cookie的過期日期,使其在用戶關閉瀏覽器后仍然存在,
  • 然而,如果你不希望資料在用戶會話結束后仍然存在,或者你希望能夠在服務器端控制資料何時過期,那么你應該選擇使用Session,

總結

總的來說,選擇使用Cookie還是Session主要取決于你的應用需求,理想情況下,你應該結合使用這兩種技術,以便最大限度地利用它們的優點,

Cookie與Session進階應用

下面,我們將介紹一些關于Cookie和Session更高級的應用,這些內容將幫助您更好地理解這兩種技術如何在復雜的Web應用中使用,

Cookie的高級應用:第三方Cookie

除了常見的“第一方”Cookie,也存在被稱為“第三方”Cookie的Cookie,這些Cookie通常用于跨網站追蹤用戶行為,例如用于廣告目標定位,了解這種型別的Cookie的作業原理,有助于我們理解和處理Cookie的隱私問題,

Session的高級應用:持久化Session

在某些情況下,我們可能希望Session在用戶關閉瀏覽器后仍然存在,這種型別的Session被稱為“持久化Session”,并且在實作用戶自動登錄等功能時非常有用,

在Django中,你可以使用SESSION_EXPIRE_AT_BROWSER_CLOSE設定來控制是否在瀏覽器關閉時過期Session,例如,你可以在你的Django設定中添加以下代碼來啟用持久化Session:

SESSION_EXPIRE_AT_BROWSER_CLOSE = False

Session的另一種存盤方式:在Cookie中存盤Session資料

盡管通常我們在服務器上存盤Session資料,但在某些情況下,我們也可以選擇在Cookie中存盤Session資料,這樣做可以減輕服務器的負擔,但需要確保Cookie的安全性,因為它們現在包含了更多的敏感資訊,

在Django中,你可以使用SESSION_COOKIE_SECURE設定來控制是否只通過HTTPS傳輸Session Cookie,例如,你可以在你的Django設定中添加以下代碼來啟用這個功能:

SESSION_COOKIE_SECURE = True

使用JSON Web Tokens (JWT) 進行認證

除了使用Cookie和Session,現在越來越多的Web應用選擇使用JSON Web Tokens (JWT)進行認證,JWT是一種開放標準,它定義了一種緊湊和自包含的方式,用于在各方之間安全地傳輸資訊作為JSON物件,這個資訊可以被驗證和信任,因為它是數字簽名的,

使用JWT進行認證的主要優點是服務器無需存盤Session狀態,這在構建可擴展的大型應用時特別有用,此外,由于JWT是自包含的,所以它們可以包含所有必要的資訊,無需進行額外的資料庫查詢,

下面是一個使用Python JWT庫創建和驗證JWT的簡單示例:

import jwt

# 創建一個新的token
payload = {"user_id": 123}
secret = 'secret'
token = jwt.encode(payload, secret, algorithm='HS256')

# 驗證并解碼token
decoded_payload = jwt.decode(token, secret, algorithms=['HS256'])
print(decoded_payload)  # 輸出: {"user_id": 123}

請注意,你需要先使用pip安裝jwt庫:

pip install PyJWT

總結

本文主要探討了Django中的Cookie和Session,以及如何在Web開發中使用它們,

  • 我們首先理解了HTTP協議的無狀態性,以及這種無狀態性如何導致Web應用需要Cookie和Session來維護狀態,
  • 然后,我們分別探討了Cookie和Session的基本概念,包括它們的作業方式、用途、優點和缺點,
  • 我們深入了解了Cookie和Session的具體實作細節,以及如何在Django中使用它們,
  • 在我們的討論中,我們也探討了一些更高級的話題,如第三方Cookie、持久化Session、在Cookie中存盤Session資料,以及使用JSON Web Tokens進行認證,

無論你是一個經驗豐富的開發者,還是一個初學者,都希望本文對你的學習有所幫助,請繼續關注我,了解更多關于Django開發的深入知識!

如有幫助,請多關注
個人微信公眾號:【Python全視角】
TeahLead_KrisChang,10+年的互聯網和人工智能從業經驗,10年+技術和業務團隊管理經驗,同濟軟體工程本科,復旦工程管理碩士,阿里云認證云服務資深架構師,上億營收AI產品業務負責人,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/557006.html

標籤:其他

上一篇:RequestContextHolder跨執行緒獲取不到requests請求物件的解決方法

下一篇:返回列表

標籤雲
其他(162374) Python(38274) JavaScript(25530) Java(18294) C(15239) 區塊鏈(8275) C#(7972) AI(7469) 爪哇(7425) MySQL(7294) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5876) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4615) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2438) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) HtmlCss(1995) .NET技术(1986) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1882) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • 跨越HTTP無狀態邊界:Cookie與Session在Django中的實戰應用

    **本文深入探索了Django中的Cookie和Session,決議了如何應對HTTP協議的無狀態性問題,說明其基礎概念,分析作業原理,并討論何時應選擇使用Cookie或Session。文章進階部分,提出高效管理Cookie和Session,以及如何利用它們進行用戶身份驗證。** ## HTTP協議 ......

    uj5u.com 2023-07-12 07:54:00 more
  • RequestContextHolder跨執行緒獲取不到requests請求物件的解決方

    # 一、前言 最近在做一個專案,有個比較耗時的操作是啟用執行緒進行異步操作,當時在啟用的執行緒時,突然發現子執行緒無法獲取父執行緒中的HttpServletRequest請求物件,因為是第一次遇到這種問題,所以記錄一下解決方案。 # 二、問題模擬 在這里,我們簡單模擬一下出現的問題。我們首先撰寫一個簡單的h ......

    uj5u.com 2023-07-12 07:53:50 more
  • 仿冒社交APP如何竊取資訊后展開勒索詐騙

    ## 起因 最近某論壇有個小伙伴求助,說自己安裝了一款 APP 后,自己的通訊錄、短信、相冊都被竊取了,進而要挾他轉賬匯款。 大概情況如下: 首先是在某社交 APP 群組中加他,好友通過后的聊天如下: ![file](https://img2023.cnblogs.com/other/606533/ ......

    uj5u.com 2023-07-12 07:51:16 more
  • 【經典爬蟲案例】用Python爬取微博熱搜榜!

    [toc] # 一、爬取目標 您好,我是[@馬哥python說](https://www.zhihu.com/people/13273183132),一名10年程式猿。 本次爬取的目標是: [微博熱搜榜](https://s.weibo.com/top/summary?cate=realtimeho ......

    uj5u.com 2023-07-12 07:44:04 more
  • 【調制解調】DSB 雙邊帶調幅

    學習數字信號處理演算法時整理的學習筆記。本篇介紹 DSB 雙邊帶調幅信號的調制與解調,內附全套 MATLAB 代碼。 ......

    uj5u.com 2023-07-11 08:21:46 more
  • 為什么使用ioutil.ReadAll 函式需要注意

    # 1. 引言 當我們需要將資料一次性加載到記憶體中,`ioutil.ReadAll` 函式是一個方便的選擇,但是`ioutil.ReadAll` 的使用是需要注意的。 在這篇文章中,我們將首先對`ioutil.ReadAll`函式進行基本介紹,之后會介紹其存在的問題,以及引起該問題的原因,最后給出了 ......

    uj5u.com 2023-07-11 08:21:41 more
  • 為什么使用ioutil.ReadAll 函式需要注意

    # 1. 引言 當我們需要將資料一次性加載到記憶體中,`ioutil.ReadAll` 函式是一個方便的選擇,但是`ioutil.ReadAll` 的使用是需要注意的。 在這篇文章中,我們將首先對`ioutil.ReadAll`函式進行基本介紹,之后會介紹其存在的問題,以及引起該問題的原因,最后給出了 ......

    uj5u.com 2023-07-11 08:20:28 more
  • Rust 使用egui創建一個簡單的下載器demo

    倉庫連接: https://github.com/GaN601/egui-demo-download-util 這是我第一個rust gui demo, 學習rust有挺長時間了, 但是一直沒有落實到實踐中, 本著對桌面應用的興趣, 考察了slint、egui兩種框架, 最后還是選擇了egui. 這 ......

    uj5u.com 2023-07-11 07:48:40 more
  • python筆記:第六章函式&方法

    # 1.系統函式 由系統提供,直接拿來用或是匯入模塊后使用 ``` a = 1.12386 result = round(a,2) print(result) > 1.12 ``` # 2.自定義函式 * 函式是結構化編程的核心 * 使用關鍵詞`def`來定義函式 ``` #函式定義 def fun ......

    uj5u.com 2023-07-11 07:48:37 more
  • == 與 equals 的區別?

    一. 介紹: Java中的 "==" 是一個運算子,是用于比較兩個物件地址值或基本資料型別之間的值是否相等。它的來源可以追溯到C語言,以及受C語言影響的許多其他編程語言。 Java中的equals() 是一個方法,可重寫該方法用于比較兩個物件屬性內容是否相等的方法。該方法繼承自Object類,在Ja ......

    uj5u.com 2023-07-11 07:48:32 more