零基础入门python23:Flask-Login登录、退出与会话

发布时间:2026/8/26 18:56:41

零基础入门python23:Flask-Login登录、退出与会话
零基础入门python23Flask-Login登录、退出与会话一、上一篇课后练习讲解邮箱大小写测试应先用AliceExample.com注册再用aliceexample.com登录并断言数据库只有一条用户记录。归一化应发生在查询和写入之前。上一篇课后练习完整答案上一篇练习的要求已落实到下面完整文件先运行项目测试再用 curl 对照状态码和数据库持久化结果答案要点注册先规范化邮箱和校验密码再生成带盐哈希唯一约束冲突捕获 IntegrityError 后 rollback 并返回 409。文件app/auth.py完整参考答案文件完整文件app/auth.pyfromflaskimportBlueprint,requestfromsqlalchemy.excimportIntegrityErrorfromwerkzeug.securityimportgenerate_password_hashfrom.extensionsimportdbfrom.modelsimportUser bpBlueprint(auth,__name__,url_prefix/api/auth)bp.post(/register)defregister():datarequest.get_json(silentTrue)or{}emailstr(data.get(email,)).strip().casefold()passwordstr(data.get(password,))ifnotinemailorlen(password)8:return{error:input_invalid},400db.session.add(User(emailemail,password_hashgenerate_password_hash(password)))try:db.session.commit()exceptIntegrityError:db.session.rollback()return{error:email_exists},409return{email:email},201完整参考答案文件本篇对应的交付源码完整文件flask-ledger/app/auth.pyfromflaskimportBlueprint,requestfromflask_loginimportcurrent_user,login_required,login_user,logout_userfrom.extensionsimportdbfrom.modelsimportUser bpBlueprint(auth,__name__,url_prefix/api/auth)bp.post(/register)defregister():datarequest.get_json(silentTrue)or{}emailstr(data.get(email,)).strip().lower()passwordstr(data.get(password,))ifnotinemail:return{message:邮箱格式不正确},400iflen(password)8:return{message:密码至少8位},400ifdb.session.scalar(db.select(User).where(User.emailemail)):return{message:邮箱已注册},409userUser(emailemail)user.set_password(password)db.session.add(user)db.session.commit()return{id:user.id,email:user.email},201bp.post(/login)deflogin():datarequest.get_json(silentTrue)or{}emailstr(data.get(email,)).strip().lower()userdb.session.scalar(db.select(User).where(User.emailemail))ifnotuserornotuser.check_password(str(data.get(password,))):return{message:邮箱或密码错误},401login_user(user)return{id:user.id,email:user.email}bp.post(/logout)login_requireddeflogout():logout_user()return{message:已退出}bp.get(/me)login_requireddefme():return{id:current_user.id,email:current_user.email}验收命令python -m pytest -qDjango 项目使用 python manage.py test。预期测试通过若失败先检查迁移、配置和事务回滚。二、本篇完成什么让注册用户登录并保持会话完成/me查看当前用户和/logout退出。登录状态由 Flask-Login 从 session 恢复受保护接口使用login_required。三、为什么不用客户端传 user_id/me从current_user.id读取身份而不是接受 JSON 中的user_id。客户端提供的 id 只是普通输入不能作为授权依据身份必须来自已经验证的 session。四、验收流程curl-c cookies.txt-X POST http://127.0.0.1:5000/api/auth/login-HContent-Type: application/json-d{\email\:\aliceexample.com\,\password\:\secret123\}curl-b cookies.txt http://127.0.0.1:5000/api/auth/me curl-b cookies.txt-X POST http://127.0.0.1:5000/api/auth/logout curl-b cookies.txt http://127.0.0.1:5000/api/auth/me预期登录和/me为 200退出后/me为 401。测试必须覆盖错误密码、未登录访问和退出后会话失效。课后练习增加会话过期配置并解释开发环境和生产环境的 Cookie 安全属性差异。项目增量Flask-Login 会话边界登录成功后使用安全 cookie 保存会话标识服务器通过 user_loader 从数据库加载用户注销必须清除会话禁用用户不能继续访问。login_manager.user_loaderdefload_user(user_id):returndb.session.get(User,int(user_id))auth_bp.post(/login)deflogin():userUser.query.filter_by(emailrequest.form[email].strip().casefold()).first()ifuserisNoneornotuser.check_password(request.form[password]):abort(401)login_user(user)returnredirect(url_for(ledger.index))验收未登录访问账目返回 401 或重定向登录后只能看到自己的数据课后练习测试 session cookie 和禁用用户。五、会话到底保存了什么Flask-Login 默认在 cookie 中保存一个不可直接信任的用户标识服务端每次请求通过user_loader查询用户。cookie 被篡改时签名校验会失败current_user变成匿名用户因此不能把“是否登录”交给前端传来的user_id。login_manager.user_loaderdefload_user(user_id:str):# 统一从数据库加载找不到用户时返回 None框架会按匿名用户处理。try:returndb.session.get(User,int(user_id))except(TypeError,ValueError):returnNonelogin_manager.unauthorized_handlerdefunauthorized():# API 客户端需要 JSON 和 401而不是浏览器登录页的 302 跳转。return{error:login_required},401登录接口不应区分“邮箱不存在”和“密码错误”否则攻击者可以枚举注册用户。remember会生成更长寿命的 cookie只有在用户明确勾选时才启用。若项目改成前后端分离并使用 JWT仍然需要保留同样的认证边界只是令牌存储位置不同。六、用测试客户端证明 cookie 生效deftest_login_session(client,user):responseclient.post(/api/auth/login,json{email:user.email,password:correct-horse})assertresponse.status_code200meclient.get(/api/auth/me)assertme.status_code200assertme.json[id]user.idclient.post(/api/auth/logout)assertclient.get(/api/auth/me).status_code401测试中必须复用同一个client因为 cookie 存在客户端对象里。出现“明明登录了仍是 401”时检查SECRET_KEY是否在每次创建应用时稳定以及user_loader是否把字符串 id 转成整数如果每次请求都创建新 client会话当然不会保留。七、禁用用户和会话失效在User增加is_active字段后is_authenticated仍然可以为真但is_active应在user_loader中检查。管理员禁用用户后下一次请求应立即失效而不是等 cookie 自然过期login_manager.user_loaderdefload_user(user_id):userdb.session.get(User,int(user_id))returnuserifuseranduser.is_activeelseNone八、上一篇练习讲解与本篇练习上一篇的并发注册测试应使用两个独立 Session本篇练习增加GET /api/auth/me和禁用用户测试要求退出后再次访问返回 401。下一篇会在这个身份基础上实现分类 CRUD并演示越权访问必须返回 404 还是 403。九、Cookie 安全实验在浏览器开发者工具的 Application → Cookies 中确认会话 cookie 具有HttpOnly和SameSiteLax若线上使用 HTTPS再打开Secure。把 cookie 的值改一个字符后重新访问/api/auth/me应得到 401说明签名校验生效。不要把 Flask 的签名 cookie 当作“加密数据库”其中内容仍可能被读取敏感资料应放服务端 Session 或数据库。如果采用前后端分离跨域请求还要正确设置 CORS 的supports_credentials并限制允许的 origin不能写*同时携带 cookie。完成实验后清理浏览器 cookie避免旧会话干扰下一次测试。本篇结束完整模块文件下面是交付项目中真实存在的完整文件 flask-ledger/app/auth.py。它覆盖本篇新增逻辑以及前文已经完成的依赖代码复制单个函数会丢失上下文因此这里提供整份文件。fromflaskimportBlueprint,requestfromflask_loginimportcurrent_user,login_required,login_user,logout_userfrom.extensionsimportdbfrom.modelsimportUser bpBlueprint(auth,__name__,url_prefix/api/auth)bp.post(/register)defregister():datarequest.get_json(silentTrue)or{}emailstr(data.get(email,)).strip().lower()passwordstr(data.get(password,))ifnotinemail:return{message:邮箱格式不正确},400iflen(password)8:return{message:密码至少8位},400ifdb.session.scalar(db.select(User).where(User.emailemail)):return{message:邮箱已注册},409userUser(emailemail)user.set_password(password)db.session.add(user)db.session.commit()return{id:user.id,email:user.email},201bp.post(/login)deflogin():datarequest.get_json(silentTrue)or{}emailstr(data.get(email,)).strip().lower()userdb.session.scalar(db.select(User).where(User.emailemail))ifnotuserornotuser.check_password(str(data.get(password,))):return{message:邮箱或密码错误},401login_user(user)return{id:user.id,email:user.email}bp.post(/logout)login_requireddeflogout():logout_user()return{message:已退出}bp.get(/me)login_requireddefme():return{id:current_user.id,email:current_user.email}

相关新闻

操作教程丨WorkBuddy 接入企业数据MCP流程与应用示例

操作教程丨WorkBuddy 接入企业数据MCP流程与应用示例

2026/8/26 18:56:41

随着 AI Agent 应用的发展,越来越多智能体开始从简单的信息问答,向任务执行和数据分析方向发展。但在实际企业场景中,模型自身掌握的信息往往无法满足实时查询需求,例如企业尽调、供应商审核、投资分析等任务,都需要结…

深入理解 AI Agent · AGENT #03:从单 Agent 到多 Agent

深入理解 AI Agent · AGENT #03:从单 Agent 到多 Agent

2026/8/26 18:46:41

📘 《深入理解 AI Agent》系列 第八篇 | AGENT-03 前篇回顾:Agent 基础篇 #01 从LLM到Agent → Agent 基础篇 #02 四大核心机制 → Agent 基础篇 #03 从单Agent到多Agent 开篇:单 Agent 能走多远? 做 AI Agent 的开发者常有一个…

Django金融时间序列数据中的异常检测与风险预警系统设计与实现机器学习选题方向大数据毕设项目

Django金融时间序列数据中的异常检测与风险预警系统设计与实现机器学习选题方向大数据毕设项目

2026/8/26 18:46:41

3.2系统可行性分析3.2.1 技术可行性​在数据处理技术方面,Python 拥有丰富的数据分析库,如 Pandas、NumPy 等,能够高效处理金融时间序列数据中的清洗、插值、标准化等任务。对于异常检测算法,无论是基于统计的 3σ 准则、贝叶斯推…

打工人如何利用AI解放双手:7步高效工作流

打工人如何利用AI解放双手:7步高效工作流

2026/8/26 20:06:44

1. 先想清楚:哪些工作适合交给 AI Agent普通人想用 AI Agent 解放双手,第一步不是急着选工具,而是先盘点自己手头有哪些「重复、有固定流程、不太需要临场判断」的工作。这类工作通常具备三个特征:重复性高:每周甚至每…

Charm-Crypto 测试与性能基准完整指南:Doctest、测试向量与 Benchmark 三步走

Charm-Crypto 测试与性能基准完整指南:Doctest、测试向量与 Benchmark 三步走

2026/8/26 20:06:44

Charm-Crypto 测试与性能基准完整指南:Doctest、测试向量与 Benchmark 三步走 【免费下载链接】charm Charm: A Framework for Rapidly Prototyping Cryptosystems 项目地址: https://gitcode.com/gh_mirrors/cha/charm Charm-Crypto 是一个用于快速原型开发…

React倒计时Hook源码深度解析:react-timer-hook的useTimer如何实现毫秒级精确倒计时?逐行精讲

React倒计时Hook源码深度解析:react-timer-hook的useTimer如何实现毫秒级精确倒计时?逐行精讲

2026/8/26 20:06:44

React倒计时Hook源码深度解析:react-timer-hook的useTimer如何实现毫秒级精确倒计时?逐行精讲 【免费下载链接】react-timer-hook React timer hook 项目地址: https://gitcode.com/gh_mirrors/re/react-timer-hook react-timer-hook 是一款专为 …

戴森球计划工厂蓝图怎么用?一份新手到进阶的完整指南

戴森球计划工厂蓝图怎么用?一份新手到进阶的完整指南

2026/8/26 20:06:44

戴森球计划工厂蓝图怎么用?一份新手到进阶的完整指南 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints FactoryBluePrints 是一个为《戴森球计划》玩家整理的社区…

什么是nestjs-starter-rest-api?一文读懂这个生产级NestJS 11单体REST API启动模板的全部功能

什么是nestjs-starter-rest-api?一文读懂这个生产级NestJS 11单体REST API启动模板的全部功能

2026/8/26 20:06:44

什么是nestjs-starter-rest-api?一文读懂这个生产级NestJS 11单体REST API启动模板的全部功能 【免费下载链接】nestjs-starter-rest-api NestJS Starter Kit. Monolithic Backend. REST API. 项目地址: https://gitcode.com/gh_mirrors/ne/nestjs-starter-rest-a…

mermaid.cli自动化实践:如何在文档工程与pre-commit工作流中批量渲染.mmd图表

mermaid.cli自动化实践:如何在文档工程与pre-commit工作流中批量渲染.mmd图表

2026/8/26 19:56:44

mermaid.cli自动化实践:如何在文档工程与pre-commit工作流中批量渲染.mmd图表 【免费下载链接】mermaid.cli Development has been moved to https://github.com/mermaid-js/mermaid-cli 项目地址: https://gitcode.com/gh_mirrors/me/mermaid.cli 一、什么是…

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

2026/8/26 1:50:39

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

2026/8/26 1:49:16

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

2026/8/26 17:50:58

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

Python random 模块常用函数详解:从入门到实战

Python random 模块常用函数详解:从入门到实战

2026/8/26 0:05:45

目录 1. 引言2. 准备工作3. 基础随机函数4. 序列相关函数5. 随机种子与复现6. 实战案例7. 注意事项8. 常见问题与排查9. 总结 1. 引言 摘要: 本文系统介绍 Python 标准库 random 模块中最常用的随机数生成函数。内容涵盖基础随机函数(random()、unifor…

Hermes接入团队协作后,我推翻了三个效率假设

Hermes接入团队协作后,我推翻了三个效率假设

2026/8/26 0:05:45

聊《Hermes真能提效吗?先看流程里最慢的那一步》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。摘要团队把 Hermes 接进项目三个月后,交付速度没有提升反而慢了。复盘后发现,最先…

免费AI大模型调教指南:打造专属网文写作助手

免费AI大模型调教指南:打造专属网文写作助手

2026/8/26 0:05:45

1. 先搞清楚“AI小说扩展模式”到底能帮你做什么如果你是一个刚开始写网文、或者卡在L3级别以下的作者,最头疼的可能是情节推进不下去、人物对话干瘪,或者世界观设定不够丰满。自己对着空白文档硬憋,效率很低。这时候,一个能理解你…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/22 2:02:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/26 18:07:30

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/26 17:57:52

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…