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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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 交叉编…