Flask 会话管理:从原理到实战,深度解析 session 机制
1、Flask
中session
的实现原理:服务器与客户端的协作
HTTP 协议是无状态的——服务器无法区分两次请求是否来自同一用户。这意味着,用户登录后跳转到其他页面时,服务器会“忘记”用户身份。
为解决这一问题,Web 开发中引入了会话管理(Session Management),根据会话的存储位置分为 服务器端存储 和 客户端存储。
Flask
的 session
是典型的客户端存储会话方案,核心依赖客户端 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 默认不提供加密,若需隐藏会话数据内容(如存储敏感信息),需通过扩展库(如
itsdangerous
或Flask-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 天有效期
相关文章:
Flask 会话管理:从原理到实战,深度解析 session 机制
1、Flask中session 的实现原理:服务器与客户端的协作 HTTP 协议是无状态的——服务器无法区分两次请求是否来自同一用户。这意味着,用户登录后跳转到其他页面时,服务器会“忘记”用户身份。 为解决这一问题,Web 开发中引入了会话…...

MySQL连接错误解决方案:Can‘t connect to MySQL server on ‘localhost‘ (10038)
错误描述 当您尝试连接MySQL数据库时,可能会遇到以下错误提示: 这个错误表明客户端无法连接到本地MySQL服务器。 可能的原因 MySQL服务未启动 MySQL配置问题 防火墙或安全软件阻止连接 端口被占用或未正确配置 网络连接问题 解决方案 方法一&am…...
【跨端框架检测】使用adb logcat检测Android APP使用的跨端框架方法总结
目录 Weex 跨端框架使用了uni-app的情况区分使用了uni-app还是Weex 判断使用了Xamarin判断使用了KMM框架判断使用了 Ionic 框架判断使用了Cordova框架判断使用了Capacitor 框架使用了React Native框架使用了QT框架使用了Cocos框架使用了Electron 框架使用了flutter 框架使用…...
lua脚本实战—— Redis并发原子性陷阱
需求分析 对于内容类网站,比如用户浏览题目的答案,需要先登录才能追溯,那么可以统计用户访问频率来限制数据的爬取。 可采用分级反爬虫策略,先告警、再采取强制措施: 如果每分钟超过 10 道题,给管理员发…...
【MySQL】第10节|MySQL全局优化与Mysql 8.0新增特性详解
全局优化 mysql server参数 1. max_connections(最大连接数) 含义:MySQL 服务允许的最大并发连接数(包括正在使用和空闲的连接)。超过此限制时,新连接会被拒绝(报错 Too many connections&am…...

CSS相关知识
1.清除浮动的方法 2.定位 静态定位相当于标准流 相对定位不脱离文档流,仍然占据原来的位置(最频繁的作用是给绝对定位当爹) 绝对定位脱离文档标准流,不再占有原来位置 3.BFC 1. 解决浮动元素导致的父容器高度塌陷 2. 阻止相邻元…...

AI扫描王APP:高效便捷的手机扫描工具,让生活更智能
AI扫描王APP是一款功能强大的手机扫描软件,专为追求高效、便捷的用户设计。它不仅支持文字提取和扫描翻译,还能进行测量,满足用户在不同场景下的需求。无论是办公、学习还是日常使用,AI扫描王都能帮助你快速完成任务,节…...

《仿盒马》app开发技术分享-- 原生地图展示(端云一体)
开发准备 上一节我们实现了获取当前用户的位置,并且成功的拿到了经纬度,这一节我们就要根据拿到的经纬度,结合我们其他的知识点来实现地图的展示。 功能分析 地图的展示,我们需要在管理中心先给我们对应的应用开启地图api功能&…...
Linux 操作文本文件列数据的常用命令
文章目录 Linux 操作文本文件列数据的常用命令基本列处理命令高级列处理列数据转换和排序列数据统计和分析 Linux 操作文本文件列数据的常用命令 Linux 提供了多种强大的命令来处理文本文件中的列数据,以下是一些最常用的命令和工具: 基本列处理命令 c…...

IP、子网掩码、默认网关、DNS
IP、子网掩码、默认网关、DNS 1. 概述1.1 windows配置处 2.IP 地址(Internet Protocol Address)2.1 公网ip2.2 内网ip2.3 🌐 公网 IP 与内网 IP 的关系(NAT) 3. 子网掩码(Subnet Mask)4. 默认网…...

华为OD机试真题——字符串加密 (2025B卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
2025 B卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...

角度回归——八参数检测四边形Gliding Vertex
文章目录 一、介绍(一)五参数检测方法( 基于角度)(二)八参数检测方法(point-based)的边界 二、方案分析(一)问题定义(二)方案…...
JVM 高质量面试题
📌 文章目录 一、JVM 内存结构与运行时模型1. JVM 内存结构分区及作用2. 栈帧结构及方法调用链维护3. 逃逸分析及其对对象分配策略的影响4. TLAB 的作用及提升对象创建效率的机制 二、垃圾回收器与 GC 调优1. CMS 与 G1 垃圾收集器的设计区别及适用场景2. Full GC 频…...

AI助力,制作视频裁剪软件
1. 视频裁剪软件套路多 最近再做一些测试,经常需要录屏什么的,有时候录制的时长视频,需要裁剪,比如去掉开头一些帧或者结尾的一些帧,就想保留关键点。但是网上下的一些软件,打开一用都是要付费的。所以想着…...
SQL注入基础
普通sql注入:后台能提供有价值的错误信息,显示在页面 手动注入 1. 寻找sql注入点 get注入 ?idxx url后加测试是否存在注入漏洞,报错则存在 post注入 把参数封装…...
使用 A2A Python SDK 实现 CurrencyAgent
谷歌官方的a2a-python SDK最近频繁的更新,我们的教程也需要跟着更新,这篇文章,我们通过 a2a-python sdk的 0.2.3 版本,实现一个简单的CurrencyAgent。 https://a2aprotocol.ai/blog/a2a-sdk-currency-agent-tutorial-zh 目录 源码准备详细过程 创建项目创建虚拟环境添加依…...
qt浏览文件支持惯性
#include <QApplication> #include <QListWidget> #include <QScroller> #include <QScrollerProperties>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 创建列表控件并添加示例项QListWidget listWidget;for (int i 0; i <…...
Python类的力量:第六篇:设计模式——Python面向对象编程的“架构蓝图”
文章目录 前言:从“代码堆砌”到“模式复用”的思维跃迁 一、创建型模式:对象创建的“智能工厂”1. 单例模式(Singleton):全局唯一的“资源管家”2. 工厂模式(Factory):对象创建的“…...

[实战]用户系统-2-完善登录和校验以及VIP
这里写目录标题 完善登录和校验新建lib-auth创建配置引入配置和JWT完善登录基本登录单点登录多点登录校验和拦截编写守卫编写装饰器使用完善VIP修改mysql模型编写vip守卫代码进度完善登录和校验 之前我们模拟过用户的登录,本节将实现token的生成,校验,redis做黑名单。我们需…...
负载均衡笔记
并发数—同时服务的调用方的数量 吞吐量—单位时间内,能接受和返回的数据请求量 TPS。 Transaction事务 QPS。Query 请求/查询 优化点: 减少并发数—防止并非过高 低级—限流—可用的用户少了?! 多开几个口—分流 DNS 解析域…...

印度语言指令驱动的无人机导航!UAV-VLN:端到端视觉语言导航助力无人机自主飞行
作者:Pranav Saxena, Nishant Raghuvanshi and Neena Goveas单位:比尔拉理工学院(戈瓦校区)论文标题:UAV-VLN: End-to-End Vision Language guided Navigation for UAVs论文链接:https://arxiv.org/pdf/250…...

mysql都有哪些锁?
MySQL中的锁机制是确保数据库并发操作正确性和一致性的重要组成部分,根据锁的粒度、用途和特性,可以分为多种类型。以下是MySQL中常见的锁及其详细说明: 一、按锁的粒度划分 行级锁(Row-level Locks) 描述:…...
解锁未来AI:使用DACA模式和Agentic技术提高开发效率
学习Agentic AI:Dapr Agentic Cloud Ascent (DACA)设计模式的应用与演进 背景介绍 近年来,Agentic AI(代理型人工智能)的概念在学术界和产业界掀起了一阵热潮。Agentic AI指的是能够自主感知、决策和行动的智能体系统,它们不仅改变了我们与技术互动的方式,也为行业发展…...

HarmonyOS NEXT 使用 relationalStore 实现数据库操作
大家好,我是V哥。在 HarmonyOS NEXT 开发中,如何操作数据库,V 哥在测试中总结了以下学习代码,分享给你,如何想要系统学习鸿蒙开发,可以了解一下 V 哥最近刚刚上架出版的 《HarmonyOS 鸿蒙开发之路 卷2 从入…...

R语言学习--Day04--数据分析技巧
在清洗完数据,在对数据分析前,我们要懂得先梳理一下我们的逻辑,即数据是什么形式的,要进行哪种分析,有可能呈现什么特点,进而再想怎么处理数据去画图可以最大程度地凸显我们要的特点。 一般来讲࿰…...

SRS流媒体服务器之RTC播放环境搭建
环境概述 srs版本 commit 44f0c36b61bc7c3a1d51cb60be0ec184c840f09d Author: winlin <winlinvip.126.com> Date: Wed Aug 2 10:34:41 2023 0800Release v4.0-r5, 4.0 release5, v4.0.271, 145574 lines. rtc.conf # WebRTC streaming config for SRS. # see full.…...

Android 性能优化入门(三)—— ANR 问题分析
需要清楚 ANR 的概念、类型、如何产生以及如何定位分析。 1、概述 1.1 ANR 的概念 ANR(Application Not Responding)应用程序无响应。如果你应用程序在主线程被阻塞太长时间,就会出现 ANR,通常出现 ANR,系统会弹出一…...
用HTML5实现实时ASCII艺术摄像头
用HTML5实现实时ASCII艺术摄像头 项目简介 这是一个将摄像头画面实时转换为ASCII字符艺术的Web应用,基于HTML5和原生JavaScript实现。通过本项目可以学习到: 浏览器摄像头API的使用Canvas图像处理技术实时视频流处理复杂DOM操作性能优化技巧 功能亮点…...

鸿蒙Flutter实战:22-混合开发详解-2-Har包模式引入
以 Har 包的方式加载到 HarmonyOS 工程 创建工作 创建一个根目录 mkdir ohos_flutter_module_demo这个目录用于存放 flutter 项目和鸿蒙项目。 创建 Flutter 模块 首先创建一个 Flutter 模块,我们选择与 ohos_app 项目同级目录 flutter create --templatemodu…...

游戏引擎学习第302天:使用精灵边界进行排序
在 game_render_group.cpp 中:正确计算 GetBoundFor() 里的 SpriteBound 值 我们正在进行游戏的排序问题调试。虽然这是一个二维游戏,但包含一些三维元素,因此排序变得比较复杂和棘手。混合二维和三维元素时,需要依赖一些比较主观…...