functools.wraps 是装饰器必备项,否则 name 和 doc 等元信息丢失,导致 help()、inspect.signature() 失效及日志、路由、openapi 异常。

用 functools.wraps 包裹装饰器,否则 __name__ 和 __doc__ 会丢
权限校验最常用的是装饰器写法,但很多人直接写个裸函数当装饰器,结果调用方查 help() 或用 inspect.signature() 就崩——因为没保留原函数元信息。functools.wraps 不是可选项,是必选项。
- 不加
@functools.wraps(func):被装饰函数的__name__变成'wrapper',日志、路由注册、OpenAPI 生成全出错 - 加了之后:所有元属性透传,调试和集成时不会突然“找不到函数”
- 常见误写:
return wrapper前漏掉@functools.wraps(func),或把functools.wraps错写成functools.wrap(少个s)
request.user 不存在?先确认中间件顺序和对象挂载时机
Flask 或 FastAPI 里常看到 if not request.user.is_admin: 报 AttributeError: 'Request' object has no attribute 'user'。这不是权限逻辑错,是 user 根本没挂上去。
- 在 Flask 中,必须确保自定义中间件(如
before_request钩子)在路由执行前运行,且明确赋值g.user = get_current_user() - FastAPI 里别在依赖函数里只做校验,忘了返回用户对象;
Depends(check_permission)如果不 return user,后续依赖拿不到request.state.user - 检查
app.middleware('http')注册顺序:认证中间件必须在权限装饰器之前执行
用 hasattr(user, 'role') 判权限?别,改用显式字段或方法
靠 hasattr 或 getattr(user, 'role', None) == 'admin' 判断,看似简单,实则埋雷:字段名拼错、空值未处理、角色继承关系无法表达。
BJXShop网上购物系统是一个高效、稳定、安全的电子商店销售平台,经过近三年市场的考验,在中国网购系统中属领先水平;完善的订单管理、销售统计系统;网站模版可DIY、亦可导入导出;会员、商品种类和价格均实现无限等级;管理员权限可细分;整合了多种在线支付接口;强有力搜索引擎支持... 程序更新:此版本是伴江行官方商业版程序,已经终止销售,现于免费给大家使用。比其以前的免费版功能增加了:1,整合了论坛
- 更稳的做法是定义
user.has_perm('delete_post')方法,在模型或用户类里集中控制逻辑 - 如果用字符串匹配,至少加一层白名单校验:
if perm not in {'read', 'write', 'admin'}:防止传入任意字符串绕过 - 数据库查角色时别用
SELECT * FROM roles WHERE name = ?—— 没索引的话,高并发下秒变慢查询
测试时 mock current_user 失效?重点看作用域和 import 路径
单元测试里用 @patch('myapp.auth.current_user'),结果运行时还是走真实认证,八成是 patch 的路径不对。
立即学习“Python免费学习笔记(深入)”;
- 必须 patch **被导入的位置**,不是定义的位置。比如模块 A 里
from flask_login import current_user,那就要@patch('A.current_user'),不是@patch('flask_login.current_user') - FastAPI 测试中,别只 mock 依赖函数,还要确保
client.get('/api', headers={'Authorization': '...'})触发了真实依赖链,否则测试通过但线上挂 - 用
pytest-mock的mocker.patch更安全,它自动处理 patch 生命周期,避免 tearDown 漏恢复
权限不是加个 if 就完事的事——它牵扯请求生命周期、对象绑定时机、测试隔离粒度,最容易出问题的地方,永远在“你以为它已经存在”的那个变量上。









