news 2026/9/6 5:44:32

Flask入门教程(十一):Session与Cookie——让应用记住用户状态

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flask入门教程(十一):Session与Cookie——让应用记住用户状态

1. Session的工作原理

Flask默认使用SecureCookieSession,它的工作方式是:

  1. Session数据被序列化后用密钥签名,保存在浏览器的Cookie

  2. 每次请求时,浏览器自动带上这个Cookie

  3. Flask验证签名后,将数据还原为Python字典供你使用

用户可以看到Cookie中的内容(因为是base64编码的),但无法篡改——因为任何修改都会导致签名验证失败。

┌─────────────┐ ┌─────────────────┐ ┌─────────────┐ │ 服务器 │ │ 浏览器 │ │ 服务器 │ │ │ 响应中 │ │ 后续请求 │ │ │ 设置session │ ────────> │ 存储session │ ────────> │ 验证签名 │ │ {"user":"A"}│ Set-Cookie│ 在Cookie中 │ Cookie │ 还原数据 │ │ │ │ │ │ {"user":"A"}│ └─────────────┘ └─────────────────┘ └─────────────┘

2. 配置SECRET_KEY

要使用Session,必须先设置SECRET_KEY——用于签名的密钥。

import secrets from flask import Flask app = Flask(__name__) # 生成一个安全的随机密钥(只在首次运行时生成即可) app.secret_key = secrets.token_hex() # 或者直接设置一个固定值(方便开发,但不要用在生产环境) # app.secret_key = "dev-secret-key-change-in-production"

⚠️重要SECRET_KEY必须保密足够随机。如果密钥泄露,任何人都可以伪造你应用的Session数据。生产环境应从环境变量或配置文件读取,不要硬编码在代码中

生成高质量密钥的命令

$ python -c 'import secrets; print(secrets.token_hex())' 192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf

3. 读写Session

session是一个类似字典的对象,用法和Python字典基本一样:

from flask import Flask, session, redirect, url_for, request app = Flask(__name__) app.secret_key = "dev-secret-key" @app.route("/") def index(): if "username" in session: return f""" <h1>欢迎回来,{session["username"]}!</h1> <p>你的访问次数:{session.get("visits", 0)}</p> <p><a href="/logout">退出登录</a></p> """ return """ <h1>RUNOOB 首页</h1> <p>你还未登录。</p> <p><a href="/login">去登录</a></p> """ @app.route("/login", methods=["GET", "POST"]) def login(): if request.method == "POST": username = request.form.get("username", "") if username: session["username"] = username session["visits"] = 0 return redirect(url_for("index")) return """ <form method="post"> <h2>登录 RUNOOB</h2> <p><input type="text" name="username" placeholder="输入用户名"></p> <p><input type="submit" value="登录"></p> </form> """ @app.route("/logout") def logout(): session.clear() # 清除session中的所有数据 # 或者只删除特定key: # session.pop("username", None) return redirect(url_for("index"))

Session常用操作

操作代码说明
设置值session["key"] = "value"存储数据
读取值session.get("key", "默认值")安全读取,不存在时返回默认值
读取值(直接)session["key"]不存在时抛出KeyError
检查是否存在"key" in session返回TrueFalse
删除特定键session.pop("key", None)删除并返回值
清除所有session.clear()清空整个session

4. 永久Session

默认情况下,Session在浏览器关闭后失效(浏览器会话级别)。如果需要「记住我」功能,可以将Session标记为永久permanent):

from datetime import timedelta # 设置永久session的有效期(默认31天) app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(days=7) @app.post("/login-remember") def login_remember(): username = request.form.get("username") if username: session["username"] = username session.permanent = True # 标记为永久session return redirect(url_for("index"))
配置默认值说明
PERMANENT_SESSION_LIFETIMEtimedelta(days=31)永久session的有效期

5. Message Flashing——一次性消息

用户提交表单后,需要显示「操作成功」或「出错」的反馈信息。这种「显示一次后消失」的消息,Flask提供了flash()机制。

后端代码

from flask import Flask, flash, get_flashed_messages, redirect, render_template, request, url_for app = Flask(__name__) app.secret_key = "dev-secret-key" @app.route("/post", methods=["GET", "POST"]) def create_post(): if request.method == "POST": title = request.form.get("title", "").strip() if not title: flash("标题不能为空", "error") return redirect(url_for("create_post")) flash(f"文章「{title}」发布成功!", "success") return redirect(url_for("create_post")) return render_template("create_post.html")

模板中渲染flash消息

templates/create_post.html:

<!DOCTYPE html> <html> <head> <title>发布文章 - RUNOOB</title> <style> .flash-success { color: green; background: #e8f5e9; padding: 10px; border-radius: 4px; } .flash-error { color: red; background: #ffebee; padding: 10px; border-radius: 4px; } .flash-info { color: blue; background: #e3f2fd; padding: 10px; border-radius: 4px; } </style> </head> <body> <h1>发布文章</h1> <!-- 获取并显示所有flash消息 --> {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} <div class="flash-{{ category }}">{{ message }}</div> {% endfor %} {% endif %} {% endwith %} <form method="post"> <p>标题:<input type="text" name="title" style="width:300px;"></p> <p><input type="submit" value="发布"></p> </form> </body> </html>

Flash消息分类

分类推荐使用场景
"message"(默认)一般通知
"success"操作成功
"error"操作失败
"warning"警告信息
"info"普通信息

Flash消息依赖于Session,因此必须设置SECRET_KEY才能使用。

6. Session与Cookie的对比

对比维度SessionCookie
存储位置服务器端(或签名后存储在客户端)客户端浏览器
数据大小受4KB限制(Flask默认方案)受4KB限制
安全性较高(数据签名防篡改)较低(用户可见可修改)
适用数据用户ID、登录状态、偏好设置跟踪标识、不敏感数据
Flask实现session对象request.cookies读取,set_cookie()写入

Cookie直接操作(不通过Session)

如果需要直接读写Cookie(不签名、不加密),可以使用以下方式:

from flask import request, make_response # 读取Cookie @app.route("/get-cookie") def get_cookie(): theme = request.cookies.get("theme", "light") return f"当前主题:{theme}" # 设置Cookie @app.route("/set-cookie") def set_cookie(): resp = make_response("Cookie已设置") resp.set_cookie("theme", "dark", max_age=60*60*24) # 有效期24小时 return resp # 删除Cookie @app.route("/delete-cookie") def delete_cookie(): resp = make_response("Cookie已删除") resp.delete_cookie("theme") return resp

7. Session常见问题与注意事项

Cookie大小限制

浏览器对单个Cookie的大小限制约为4KB不要在Session中存储大量数据——适合存用户ID、偏好设置等轻量信息,不适合存文件或大型对象。

Session数据可见性

Flask默认的Session数据只是被签名(防篡改),并未加密。用户可以通过base64解码看到Session的内容。因此:

  • ✅ 适合存储:用户ID、用户名、偏好设置(非敏感)

  • ❌ 不适合存储:密码、信用卡号、个人隐私信息

生产环境密钥管理

import os # 从环境变量读取密钥(生产环境推荐) app.secret_key = os.environ.get("SECRET_KEY") # 如果环境变量未设置,给出明确错误提示 if not app.secret_key: raise ValueError("SECRET_KEY environment variable not set")

小结

本章全面讲解了Flask的Session与Cookie机制。Session通过签名Cookie实现有状态的Web应用,使用前必须配置SECRET_KEYsession对象类似字典,支持读写、删除和清空操作;通过设置session.permanent = True可让Session在浏览器关闭后仍然有效,有效期由PERMANENT_SESSION_LIFETIME控制;flash()消息闪现机制用于一次性用户反馈,配合模板中的get_flashed_messages()使用。Session数据有4KB大小限制且仅签名未加密,适合存储用户ID等轻量非敏感信息,不适合存储敏感数据。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 7:41:51

计算机毕业设计之基于Android平台的爱心猫窝APP的设计与开发

随着网络科技的发展&#xff0c;移动智能终端逐渐走进人们的视线&#xff0c;相关应用越来越广泛&#xff0c;并在人们的日常生活中扮演着越来越重要的角色。因此&#xff0c;关键应用程序的开发成为影响移动智能终端普及的重要因素&#xff0c;设计并开发实用、方便的应用程序…

作者头像 李华
网站建设 2026/9/2 7:59:23

LLM输出去AI味工程化实操:提示词、参数、后处理与部署指南

“Humanising LLM Outputs Is Dumb”不是一个开源仓库的名字&#xff0c;而是一句争议不小的观点。它反对的不是“让 AI 写作更自然”&#xff0c;而是那种为了“像人”而盲目堆砌口语、加语气词、假装有情绪的提示词工程思路。放在工程语境里&#xff0c;这句话真正想说的是&a…

作者头像 李华
网站建设 2026/9/5 21:04:35

Cohere企业级大模型API实战:从多伦多大学到RAG部署

这次我们来看的&#xff0c;不是某个新开源 UI&#xff0c;而是 Cohere 的成长路径&#xff1a;Cohere CEO 谈多伦多大学与 AI 之路。如果你在做大模型 API 选型&#xff0c;Cohere 是一个绕不过去的名字。它由《Attention Is All You Need》作者之一 Aidan Gomez 联合创立&…

作者头像 李华
网站建设 2026/9/2 11:02:46

Claude Morning Brief推送背后:先把Claude Code环境跑通

早上打开电脑&#xff0c;消息列表里多了一条来自 Claude 的推送&#xff0c;标题写着“Morning Brief”。点开之后&#xff0c;里面列着昨天项目仓库的关键变化、几个尚未完成的任务提醒&#xff0c;还有一条关于当前分支的简短总结。说实话&#xff0c;第一反应不是“这个功能…

作者头像 李华
网站建设 2026/9/2 11:42:01

测试核心是质量风险:从面试题到测试思维与用例设计实战

我最近参与了几场测试岗面试&#xff0c;有一幕印象特别深。候选人简历上写着熟悉自动化测试、接口测试、性能测试&#xff0c;看起来准备得很充分。结果我问了一句“你觉得测试核心是什么”&#xff0c;对方愣了几秒&#xff0c;然后说&#xff1a;“测试就是找bug&#xff0c…

作者头像 李华