Flask 會話管理:從原理到實戰,深度解析 session 機制

1、Flasksession 的實現原理:服務器與客戶端的協作

HTTP 協議是無狀態的——服務器無法區分兩次請求是否來自同一用戶。這意味著,用戶登錄后跳轉到其他頁面時,服務器會“忘記”用戶身份。

為解決這一問題,Web 開發中引入了會話管理(Session Management),根據會話的存儲位置分為 服務器端存儲 和 客戶端存儲。

Flasksession 是典型的客戶端存儲會話方案,核心依賴客戶端 Cookie 存儲數據,服務器僅負責生成簽名、驗證數據完整性。以下從服務器角色客戶端角色兩部分拆解其實現原理。

1.1、服務器角色

1.1.1、生成簽名:響應階段(用戶登錄等場景)

當用戶觸發會話創建(如登錄成功),服務器執行以下步驟:

  • 步驟1:數據序列化:將會話數據(如 {"username": "alice", "is_login": True})序列化為 JSON 格式({"username":"alice","is_login":True})。
  • 步驟2:Base64編碼:將 JSON 字符串通過 Base64 編碼為“數據部分”(如 eyJ1c2VybmFtZSI6ImFsaWNlIiwiaXNfbG9naW4iOnRydWV9)。
  • 步驟3:生成HMAC簽名:使用 secret_key 對“數據部分”生成 HMAC 簽名(“簽名部分”,如 YlZ4Vg)。
  • 步驟4:組裝Cookie:將“數據部分”與“簽名部分”用 . 連接,形成完整的 Cookie 值(數據部分.簽名部分)。
  • 步驟5:返回客戶端:通過響應頭 Set-Cookie: session=數據部分.簽名部分; ... 將 Cookie 發送給客戶端。

1.1.2、驗證簽名:請求階段(用戶訪問其他頁面)

用戶后續訪問頁面時,客戶端會攜帶 Cookie 發送請求,服務器執行以下驗證:

  • 步驟1:提取Cookie:從請求頭中讀取 session Cookie 的值(數據部分.簽名部分)。
  • 步驟2:拆分數據與簽名:將 Cookie 值按 . 拆分為“數據部分”和“簽名部分”。
  • 步驟3:重新計算簽名:使用相同的 secret_key 對“數據部分”重新生成 HMAC 簽名。
  • 步驟4:比對簽名:若新生成的簽名與 Cookie 中的“簽名部分”一致,說明數據未被篡改,會話有效;否則標記會話無效(如視為未登錄)。

1.2、客戶端角色

1.2.1、存儲Cookie:接收并持久化

瀏覽器接收到服務器返回的 Set-Cookie 響應頭后,會將會話 Cookie 存儲在本地(如內存或硬盤)。默認情況下,Cookie 是“臨時會話”(關閉瀏覽器后刪除),若通過 session.permanent = True 可設置為長期有效(如31天)。

1.2.2、攜帶Cookie:自動附加請求

每次向同一域名發送請求時,瀏覽器會自動將 session Cookie 附加到請求頭中(格式:Cookie: session=數據部分.簽名部分)。這一行為由瀏覽器自動完成,用戶無需手動操作。

1.2.3、無法篡改數據:簽名機制限制

客戶端可以查看 Cookie 中的“數據部分”(Base64 解碼后為明文 JSON),但無法安全篡改數據:

  • 若修改“數據部分”(如將 username 改為 admin),需同時偽造匹配的“簽名部分”;
  • 由于簽名依賴服務器私有的 secret_key,攻擊者無法生成合法簽名,篡改后的數據會被服務器驗證拒絕。

這一設計使 Flask session 具備輕量、分布式友好的優勢,但也因客戶端存儲的特性,存在數據大小限制(4KB)和明文存儲敏感信息的風險。實際開發中,需根據場景選擇是否擴展至服務器端存儲(如 Flask-Session 結合 Redis)。


2、基礎使用:從初始化到增刪改查

2.1、初始化:設置 secret_key

服務器使用 secret_key 對會話數據生成一個哈希簽名(HMAC),并將會話數據與簽名一起存入 Cookie(格式:數據部分.簽名部分)。

簽名僅驗證數據完整性,不隱藏數據內容,會話數據在 Cookie 中以明文(Base64 編碼的 JSON)存儲,客戶端可直接解碼查看(如通過瀏覽器開發者工具)。

from flask import Flask, session  app = Flask(__name__)  
# 必須設置 secret_key(生產環境需使用高強度隨機字符串,如 os.urandom(24) 生成)  
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'  # 示例密鑰(實際需替換)  

Flask 默認不提供加密,若需隱藏會話數據內容(如存儲敏感信息),需通過擴展庫(如 itsdangerousFlask-EncryptedSession)對數據加密后再簽名。

2.2、常用操作:增、查、刪、清

2.2.1、存儲數據:設置會話變量

通過字典賦值語法,將會話數據存入 session

@app.route('/login', methods=['POST'])  
def login():  username = request.form.get('username')  # 假設用戶驗證通過(如數據庫查詢)  session['username'] = username  # 存儲用戶名到 session  session['is_admin'] = False       # 存儲布爾值  return redirect(url_for('profile'))  

2.2.2、讀取數據:獲取會話變量

讀取會話數據時,Flask session 支持兩種方式:通過 session.get() 安全獲取,或直接通過 session[key] 取值。

2.2.2.1、session.get(key, default=None)

get() 方法是更推薦的讀取方式,核心優勢是鍵不存在時返回默認值(默認 None,避免 KeyError 異常導致應用崩潰。

示例

@app.route('/profile')  
def profile():  # 使用 get() 讀取,無 username 鍵時返回 None  username = session.get('username')  if not username:  return redirect(url_for('login'))  # 未登錄則跳轉  return f"歡迎,{username}!"  
2.2.2.2、session[key]

若明確會話中存在目標鍵,可直接通過 session[key] 取值。
但需注意:鍵不存在時會拋出 KeyError 異常,需配合 try-except 捕獲異常,否則可能導致服務器返回 500 錯誤。

示例(需配合異常處理)

@app.route('/dashboard')  
def dashboard():  try:  # 直接取值(假設用戶已登錄,username 必然存在)  username = session['username']  return f"管理面板 - 歡迎 {username}!"  except KeyError:  return redirect(url_for('login'))  # 未登錄時捕獲異常并跳轉  

2.2.3、刪除數據:移除指定會話變量

使用 session.pop(key) 或直接 del session[key] 刪除指定鍵:

@app.route('/logout')  
def logout():  session.pop('username')  # 移除用戶名  # 或 del session['username'](無該鍵時會拋 KeyError)  return redirect(url_for('login'))  

2.2.4、清除所有數據:銷毀會話

使用 session.clear() 清空當前會話的所有數據:

@app.route('/reset')  
def reset():  session.clear()  # 清空會話  return "會話已重置"  

3、安全實踐:避免會話攻擊的關鍵配置

3.1、secret_key:會話安全的“命門”

  • 必須保密secret_key 泄露會導致攻擊者偽造或篡改會話數據(如生成包含任意 username 的 Cookie)。
  • 生產環境建議
    • 不要硬編碼在代碼中(通過環境變量或配置文件讀取)。
    • 使用至少 32 字節的隨機字符串(如 import os; app.secret_key = os.urandom(32))。

3.2、Cookie 安全標志:防御 XSS 與 CSRF

Flask session 本質是一個 Cookie,通過設置以下標志增強安全性:

配置項作用生產環境建議
session.cookie_secure僅允許 HTTPS 傳輸 Cookie(防止中間人攻擊竊取 Cookie 明文)設為 True(需部署 HTTPS)
session.cookie_httponly禁止 JavaScript 訪問 Cookie(防御 XSS 攻擊讀取會話數據)設為 True(默認已開啟)
session.cookie_samesite限制 Cookie 僅在同站點請求中發送(防御 CSRF 攻擊偽造請求攜帶 Cookie)設為 'Lax''Strict'

配置示例

app.config.update({  'SESSION_COOKIE_SECURE': True,    # 僅 HTTPS  'SESSION_COOKIE_HTTPONLY': True,  # 禁止 JS 訪問  'SESSION_COOKIE_SAMESITE': 'Lax'  # 同站點策略  
})  

3.3、會話有效期:控制用戶“保持登錄”

默認情況下,Flask session臨時會話(關閉瀏覽器后失效)。若需長期有效(如“記住我”功能),可通過 session.permanent = True 設置:

3.3.1、設置永久會話

@app.route('/login', methods=['POST'])  
def login():  # ... 驗證邏輯 ...  session['username'] = username  session.permanent = True  # 開啟永久會話(默認有效期 31 天)  return redirect(url_for('profile'))  

3.3.2、自定義有效期

通過 app.config['PERMANENT_SESSION_LIFETIME'] 自定義有效期(需導入 timedelta):

from datetime import timedelta  app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)  # 7 天有效期  

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

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

相關文章

學習STC51單片機16(芯片為STC89C52RCRC)

每日一言 那些讓你喘不過氣的日子,正是蛻變的開始。 串口編程寄存器分析(紅色框里面的這個是串口助手里面生成的波特率初始化函數哈) 我們就根據以上的寄存器分析,因為這個是配置波特率的需要的寄存器 PCON smod 0 就是PCON的bit…

crud方法命名示例

以下是基于表名dste_project_indicator(項目指標表)的完整命名示例,覆蓋各類增刪改查場景: 1. 表名與實體類映射 // 表名:dste_project_indicator // 實體類:DsteProjectIndicatorEntity public class Ds…

AI時代新詞-人工智能生成內容(AIGC)

一、什么是人工智能生成內容(AIGC)? 人工智能生成內容(Artificial Intelligence Generated Content,簡稱AIGC)是指利用人工智能技術生成的各種形式的內容,包括文字、圖像、音頻和視頻等。AIGC的…

英語六級-閱讀篇

目錄 2023年12月大學英語真題(二) 十五選十(Section A) 單詞表 短語表 譯文 Passage Two(Section C) 單詞表 短語表 譯文 簡介:其實我總結這篇文章就是平時記憶該閱讀文章單詞中出現的…

Python 爬蟲開發

文章目錄 1. 常用庫安裝2. 基礎爬蟲開發2.1. 使用 requests 獲取網頁內容2.2. 使用 BeautifulSoup 解析 HTML2.3. 處理登錄與會話 3. 進階爬蟲開發3.1. 處理動態加載內容(Selenium)3.2. 使用Scrapy框架3.3. 分布式爬蟲(Scrapy-Redis&#xff…

為什么需要清除浮動?清除浮動的方式有哪些?

導語: 在前端面試中,“清除浮動”幾乎是每位面試官都會問到的基礎題。雖然浮動已經不如 Flex 和 Grid 那么常用了,但它在許多老項目中仍然占有一席之地。理解浮動的機制、掌握清除浮動的方式,是面試中體現你前端基礎扎實度的關鍵點。 一、面試主題概述 浮動(float)最初是…

一鍵啟動多個 Chrome 實例并自動清理的 Bash 腳本分享!

目錄 一、📦 腳本功能概覽 二、📜 腳本代碼一覽 三、🔍 腳本功能說明 (一)? 支持批量啟動多個 Chrome 實例 (二)? 每個實例使用獨立用戶數據目錄 (三)? 啟動后自…

2025.05.26【Wordcloud】詞云圖繪制技巧

Most basic See what input file is needed to build this basic wordcloud. Text analysis A text analysis by Benjamin Tovarcis for document classification. 文章目錄 Most basicText analysis 探索詞云圖的奧秘什么是詞云圖?為什么使用詞云圖?如…

RuoYi前后端分離框架集成UEditorPlus富文本編輯器

一、背景 采用若依框架搭建了一個小型的電子書項目,項目前端、后端、移動端就一人,電子書的章節內容是以富文本內容進行呈現的,產品設計人員直接給了一個第三方收費的富文本編輯器截圖放到開發文檔中,提了一沓需求點,概況下來就是要做成下圖中的樣子。作為一個后端開發人…

ETL 工具與數據中臺的關系與區別

ETL 工具和數據中臺作為數據處理領域的關鍵概念,雖然存在一定的關聯,但二者有著明顯的區別。本文將深入剖析 ETL 工具與數據中臺之不同。 一、ETL 工具概述 ETL 是數據倉庫技術中的核心技術之一,其全稱為 Extract(抽取&#xff…

Redis(四) - 使用Python操作Redis詳解

文章目錄 前言一、下載Python插件二、創建項目三、安裝 redis 庫四、新建python軟件包五、鍵操作六、字符串操作七、列表操作八、集合操作九、哈希表操作十、有序集合操作十一、完整代碼1. 完整代碼2. 項目下載 前言 本文是基于 Python 操作 Redis 數據庫的實戰指南&#xff0…

xdvipdfmx:fatal: File ended prematurely. No output PDF file written.

今天忽然遇到:使用xelatex或lualatex編譯,一直卡住,不報錯,也無法生成PDF,主動停止編譯后就報錯 xdvipdfmx:fatal: File ended prematurely. No output PDF file written. 然后,之前能正常編譯的一些文件…

解鎖未來AI:使用DACA模式和Agentic技術提高開發效率

學習Agentic AI:Dapr Agentic Cloud Ascent (DACA)設計模式的應用與演進 背景介紹 近年來,Agentic AI(代理型人工智能)的概念在學術界和產業界掀起了一陣熱潮。Agentic AI指的是能夠自主感知、決策和行動的智能體系統,它們不僅改變了我們與技術互動的方式,也為行業發展…

Jenkins+Docker+Harbor快速部署Spring Boot項目詳解

JenkinsDockerHarbor快速部署Spring Boot項目詳解 Jenkins、Docker和Harbor是現代DevOps流程中的核心工具,結合使用可以實現自動化構建、測試和部署。下面我將詳細介紹如何搭建這個集成環境。 一、各工具的核心作用 Jenkins 自動化CI/CD工具,負責拉取代…

第12次04 :首頁展示用戶名

登錄后&#xff0c;跳轉到首頁&#xff0c;首頁會展示用戶名&#xff1b;未登錄時&#xff0c;首頁將展示登錄與注冊的選項。 第一步&#xff1a;index.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml…

Flask 路由跳轉機制:url_for生成動態URL、redirect頁面重定向

在 Flask 開發中&#xff0c;url_for() 與 redirect() 是實現路由跳轉邏輯的核心工具。 url_for()負責安全、靈活地生成 URL。 redirect()負責發起重定向響應。 1、url_for()&#xff1a;生成URL url_for(endpoint, **values) 是 Flask 提供的 URL 構造工具&#xff0c;可根據…

華為OD機試真題——構成正方形的數量(2025B卷:100分)Java/python/JavaScript/C++/C/GO六種最佳實現

2025 B卷 100分 題型 本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析; 并提供Java、python、JavaScript、C++、C語言、GO六種語言的最佳實現方式! 本文收錄于專欄:《2025華為OD真題目錄+全流程解析/備考攻略/經驗分享》 華為OD機試真題《構成…

FFMPEG-AAC編碼

一、流程圖 二、代碼解釋 avcodec_find_encoder: 根據指定的AVCodecID查找注冊的編碼器。avcodec_alloc_context3: 為AVCodecContext分配內存。()avcodec_open2: 打開編碼器。avcodec_send_frame: 將AVFrame?壓縮數據給編碼器。avcodec_receive_packet: 獲取到編碼后的…

RPC 協議詳解、案例分析與應用場景

一、RPC 協議原理詳解 RPC 協議的核心目標是讓開發者像調用本地函數一樣調用遠程服務&#xff0c;其實現過程涉及多個關鍵組件與流程。 &#xff08;一&#xff09;核心組件 客戶端&#xff08;Client&#xff09;&#xff1a;發起遠程過程調用的一方&#xff0c;它并不關心調…

Docker基礎 -- Ubuntu 22.04 AArch64 交叉編譯 Docker 鏡像構建指南

Ubuntu 22.04 AArch64 交叉編譯 Docker 鏡像構建指南 作者&#xff1a; &#xff08;填寫作者&#xff09; 發布日期&#xff1a; 2025?05?26 1 背景與目標 在企業內網&#xff08;需要代理&#xff09;環境下&#xff0c;我們需要一套可靠、可復用的 Ubuntu 22.04 交叉編…