当前位置: 首页 > article >正文

不止于JWT:用FastAPI的Depends实现细粒度权限控制

本文摘要很多FastAPI初学者把JWT认证当成权限控制的终点结果上线后频繁出现越权操作。本文通过一个真实的“多租户Todo”案例带你从0搭建基于角色的访问控制RBAC和数据级权限ABAC手撕权限拦截代码分享我常用的依赖封装方案。 第一部分只有JWT到底缺了啥先别急着写代码咱们捋一捋最常见的翻车现场。想象你的API是一个高档小区。JWT就像门禁卡——刷卡能进小区大门通过认证。但进门之后你能随便进别人家吗能去物业办公室调监控吗显然不行。你需要“房间钥匙”和“工作证”。很多初版代码长这样app.get(/tasks/{task_id}) def get_task(task_id: int, user: User Depends(get_current_user)): task db.query(Task).filter(Task.id task_id).first() return task # 危险没检查这个task是不是该用户的⚠️ 警告这段代码等于让张三拿着身份证就能进李四家拿东西。只要用户伪造或篡改了token里的user_id甚至只是猜到别人的ID数据就裸奔了。 第二部分细粒度权限到底“细”在哪儿咱们做权限通常分三个层级你可以对着看看自己项目到哪一步了①全局认证Authentication你是谁——JWT搞定。②角色权限RBAC你有什么身份——比如“管理员”能删除“普通用户”只能看。③数据权限ABAC/行级你对这个具体的数据有什么权限——比如“只能改自己创建的任务”或“状态为‘草稿’的文章才能编辑”。今天重点聊②和③因为这是最容易被忽略的“隐形漏洞”。️ 第三部分实战用Depends写一个“带脑子的”权限拦截器FastAPI的Depends简直是权限控制的瑞士军刀。它不仅能拿用户信息还能嵌套依赖、提前拦截请求比在路由函数里写一堆if判断优雅一万倍。 第一步给JWT加点“料”别再只存个user_id了生成token的时候把角色(role)和权限标识(permissions)塞进payload里后续查询会省很多事儿。# 登录时生成token def create_access_token(data: dict, expires_delta: timedelta None): to_encode data.copy() # 除了user_id把角色和权限列表放进去 to_encode.update({ role: user.role, perms: user.permissions # 比如 [task:create, task:delete_own] }) return jwt.encode(to_encode, SECRET_KEY, algorithmALGORITHM)⚙️ 第二步封装权限校验依赖核心干货这里咱们写一个“可配置”的权限依赖。它的工作流程是拿到token - 解析用户 - 检查角色 - 检查具体权限。只要不通过直接抛403路由函数根本不会执行。from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from typing import List, Optional oauth2_scheme OAuth2PasswordBearer(tokenUrltoken) # 模拟获取当前用户实际项目中会查DB或解码JWT async def get_current_user(token: str Depends(oauth2_scheme)): try: payload jwt.decode(token, SECRET_KEY, algorithms[ALGORITHM]) user_id: str payload.get(sub) role: str payload.get(role) perms: List payload.get(perms, []) if user_id is None: raise HTTPException(status_code401, detail无效凭证) return {id: user_id, role: role, permissions: perms} except jwt.PyJWTError: raise HTTPException(status_code401, detail无效凭证) # 重磅可组合的权限依赖 class PermissionChecker: def __init__(self, required_role: Optional[str] None, required_perm: Optional[str] None): self.required_role required_role self.required_perm required_perm def __call__(self, user: dict Depends(get_current_user)): # 角色检查RBAC if self.required_role and user.get(role) ! self.required_role: raise HTTPException( status_codestatus.HTTP_403_FORBIDDEN, detailf需要 {self.required_role} 角色 ) # 权限检查细粒度 if self.required_perm and self.required_perm not in user.get(permissions, []): raise HTTPException( status_codestatus.HTTP_403_FORBIDDEN, detailf缺少权限: {self.required_perm} ) return user # 通过检查把用户信息传给路由用 第三步在路由中使用清爽到飞起看看封装后的效果是不是比在函数里写一堆 if 舒服多了# 实例化不同的权限检查器 require_admin PermissionChecker(required_roleadmin) require_task_create PermissionChecker(required_permtask:create) require_task_delete_own PermissionChecker(required_permtask:delete_own) # 只有admin能删任何任务 app.delete(/tasks/{task_id}) async def delete_task_any(task_id: int, admin_user: dict Depends(require_admin)): # 业务逻辑直接删反正已经确认是admin return {msg: 任务已删除} # 用户只能删自己的任务这里只检查了“是否有删除自己任务的权限”具体数据还得再查 app.delete(/tasks/my/{task_id}) async def delete_my_task(task_id: int, user: dict Depends(require_task_delete_own)): task db.query(Task).filter(Task.id task_id).first() if task.owner_id ! user[id]: raise HTTPException(status_code403, detail只能删除自己的任务) db.delete(task) return {msg: 自己的任务已删除} 第四部分进阶玩法——数据级权限ABAC上面代码里还有个瑕疵require_task_delete_own只保证了“用户有删除自己任务的权限”但没保证“这个任务真的是他的”。这就是典型的数据级权限缺失。更优雅的做法是把“数据归属校验”也封装进依赖里。参考fastapi-permissions库的思路可以给每个数据模型定义一个“权限控制列表”ACLfrom fastapi_permissions import Allow, Authenticated class Task: def __acl__(self): return [ (Allow, Authenticated, view), (Allow, fuser:{self.owner_id}, edit), (Allow, role:admin, delete), ]然后在依赖里把当前用户的principals身份列表和资源的ACL进行比对。如果 “user:123” 不在允许列表里直接 403。这样就把权限逻辑和数据模型绑定了维护起来特别清晰。 第五部分这些坑我帮你踩过了 坑1把权限逻辑写在路由函数里我当时为了赶进度在每个路由里都写 if user.role ! admin: raise ...。后来权限逻辑变了要加个“超级管理员”我改了18个文件改到吐。所以一定用Depends集中管理 坑2JWT里不放权限每次都查DB虽然查DB更实时但高频接口扛不住啊。我后来折中方案核心权限放JWT只读易变权限单独查缓存Redis。 坑3忘了异常处理导致服务器500权限校验失败一定要 raise HTTPException不要 return None 或者直接 pass不然FastAPI会继续执行路由可能触发更奇怪的数据库错误。

相关文章:

不止于JWT:用FastAPI的Depends实现细粒度权限控制

📌 本文摘要 很多FastAPI初学者把JWT认证当成权限控制的终点,结果上线后频繁出现越权操作。本文通过一个真实的“多租户Todo”案例,带你从0搭建基于角色的访问控制(RBAC)和数据级权限(ABAC)&…...

深度解析Synology Photos面部识别补丁:从技术原理到实战部署完整指南

深度解析Synology Photos面部识别补丁:从技术原理到实战部署完整指南 【免费下载链接】Synology_Photos_Face_Patch Synology Photos Facial Recognition Patch 项目地址: https://gitcode.com/gh_mirrors/sy/Synology_Photos_Face_Patch Synology Photos Fa…...

[具身智能-170]:在具身智能的技术路径中,其中大小脑联合架构是务实的架构成为行业当下的共识,如果要学习大脑,需要学习哪些技术?已经学习的路径建议。

在具身智能的“大小脑”联合架构中,“大脑”主要负责高层级的语义理解、任务规划和决策,相当于机器人的“认知与思考中心”。要深入学习这一领域,你需要掌握一系列前沿的AI技术,并遵循一个循序渐进的学习路径。🧠 具身…...

VASP机器学习力场训练避坑指南:从INCAR参数设置到声子谱验证的完整流程

VASP机器学习力场训练实战:参数调优与声子谱诊断全解析 在材料计算领域,VASP结合机器学习力场的技术路线正逐渐成为平衡计算精度与效率的黄金标准。但当我们真正着手训练自己的力场模型时,往往会发现教程中的理想案例与实际操作之间存在巨大鸿…...

零成本构建3D资源库:Firefox专属Sketchfab模型下载方案

零成本构建3D资源库:Firefox专属Sketchfab模型下载方案 【免费下载链接】sketchfab sketchfab download userscipt for Tampermonkey by firefox only 项目地址: https://gitcode.com/gh_mirrors/sk/sketchfab 在数字内容创作领域,高质量3D模型资…...

Jetson Orin R36.4.4内核编译与设备树定制实战:从.config修改到DTB生成

Jetson Orin R36.4.4内核编译与设备树定制实战:从.config修改到DTB生成 在嵌入式开发领域,Jetson Orin系列以其强大的AI算力和灵活的扩展性成为边缘计算的热门选择。但当我们需要连接特定传感器或外设时,标准系统镜像往往无法满足需求——这正…...

TranslucentTB:Windows任务栏透明化与个性化定制工具完全指南

TranslucentTB:Windows任务栏透明化与个性化定制工具完全指南 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB TranslucentTB是…...

手机当主力开发机?用Termux配置SSH连接远程服务器的完整流程(附防断连技巧)

手机变身开发终端:Termux全流程SSH配置与移动办公实战 在咖啡厅等朋友时突然需要紧急修复服务器故障,出差途中发现生产环境告警却找不到电脑——这些场景下,你的Android手机完全可以成为救命稻草。Termux这款终端模拟器配合SSH,能…...

SigmaStar SSD21X系列芯片:智能家居与工业控制的多场景显示解决方案

1. SigmaStar SSD21X系列芯片:智能家居与工业控制的显示利器 第一次接触SigmaStar SSD21X系列芯片是在一个智能门锁项目上。当时客户要求低成本实现高清彩色触控屏,还要支持人脸识别和远程控制。测试了几款方案后,SSD210的表现让我印象深刻—…...

如何突破微信设备限制?WeChatPad带来的多设备协同新体验

如何突破微信设备限制?WeChatPad带来的多设备协同新体验 【免费下载链接】WeChatPad 强制使用微信平板模式 项目地址: https://gitcode.com/gh_mirrors/we/WeChatPad 问题引入:微信生态的设备枷锁 当代数字生活中,微信已成为不可或缺…...

OpenClaw 的模型架构中,是否使用了混合专家(MoE)的负载均衡策略?

关于OpenClaw模型架构中是否采用了混合专家(MoE)的负载均衡策略,这个问题其实触及了当前大模型设计里一个相当有意思的细节。直接说结论的话,从目前公开的论文和技术报告来看,OpenClaw并没有明确声明在其MoE层中使用了…...

Ubuntu 24.04 时间同步踩坑记:从 hwclock 到 timedatectl 的演进与实战

Ubuntu 24.04 时间同步踩坑记:从 hwclock 到 timedatectl 的演进与实战 记得第一次在 Ubuntu 24.04 上看到系统时间与 Windows 11 相差整整 8 小时时,我下意识地敲下了熟悉的 hwclock 命令——这个陪伴我多年的老伙计。然而终端冰冷的报错提示让我意识到…...

阿里云RocketMQ LiteTopic:破解高并发智能语音交互消息链路难题

【导语:随着AI Agent从文本交互走向语音交互,高并发场景下消息链路瓶颈凸显。阿里云基于RocketMQ LiteTopic构建实时语音消息链路架构,解决传统架构难题,提升业务价值。】高并发语音交互的技术瓶颈当AI Agent语音交互进入高并发场…...

高效视频素材全流程管理工具:Cobalt 开源解决方案详解

高效视频素材全流程管理工具:Cobalt 开源解决方案详解 【免费下载链接】cobalt save what you love 项目地址: https://gitcode.com/GitHub_Trending/cob/cobalt Cobalt 是一款专为内容创作者设计的高效视频素材管理工具,支持从 30 主流平台下载视…...

HIT-哈工大软件过程与项目管理:从理论到实战的备考精要与核心脉络梳理

1. 软件过程与项目管理课程概述 哈工大软件过程与项目管理课程是软件工程专业的核心课程之一,旨在帮助学生掌握软件开发全生命周期的管理方法。这门课程将理论与实践紧密结合,涵盖了从需求分析到软件维护的完整知识体系。 作为一门典型的工科课程&#x…...

Python实战:高效破解RAR加密文件的自动化脚本设计

1. 为什么需要RAR密码破解脚本 在日常工作中,我们经常会遇到这样的尴尬情况:一个重要的RAR压缩文件,明明是自己设置的密码,却怎么也想不起来了。这时候,一个能够自动尝试各种密码组合的Python脚本就能派上大用场。 RAR…...

Mysql 支持的复制类型

MySQL 的复制可以从两个维度进行分类,分别对应数据一致性和日志格式。下面分别说明。 一、按数据一致性分类 复制类型 机制 优点 缺点 适用场景 异步复制 主库提交事务后立即返回,不等待从库确认 性能最高,主库无延迟 主库故障可能丢失已提交事务 对一致性要求不高的场景(如…...

机器人避障轨迹优化实战:用Python+Scipy从数学推导到完整代码实现

机器人避障轨迹优化实战:PythonScipy从数学建模到工程实现 当你在机器人实验室里第一次看到机械臂撞翻咖啡杯,或是无人机在演示中撞上窗帘时,就会明白轨迹优化不仅仅是数学公式——它是让机器人安全高效工作的核心技术。本文将带你从零开始&a…...

Mysql 主从复制详解

MySQL 主从复制详解 MySQL 主从复制是数据库高可用架构的基石,也是系统分析师考试中数据库部分的高频考点。下面从核心原理、复制类型、架构模式、配置实战到运维监控进行全面解析。 📌 一、主从复制核心概念 定义与目的 主从复制是指将主数据库(Master)的数据变化实时…...

SMUDebugTool效能优化手册:3大核心场景的性能突破之道

SMUDebugTool效能优化手册:3大核心场景的性能突破之道 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gi…...

Meta超智能体开源:任意可计算任务中,能自我改进实现无尽演化

AI已经从被动解答问题的工具,演化为能主动探索如何进化的计算实体了。Meta人工智能实验室联合英属哥伦比亚大学、矢量研究所、爱丁堡大学以及纽约大学等多家顶尖学术机构的科研团队,共同推出了极具前沿性的架构设计DGM-Hyperagents。DGM-Hyperagents把执…...

别再只盯着TOF了!聊聊FMCW激光雷达:它凭什么能直接测速,还自带‘抗干扰’光环?

FMCW激光雷达:重新定义自动驾驶感知边界的三大技术革命 当特斯拉的纯视觉方案与激光雷达阵营的路线之争还在持续时,一种被称为"激光雷达中的特斯拉"的技术正在悄然改写游戏规则。FMCW(调频连续波)激光雷达不像传统TOF&a…...

听说读写画样样精通!美团开源LongCat-Next,给物理世界AI统一了语言

美团刚刚开源了最强原生多模态模型LongCat-Next,将物理世界AI的语言统一了。LongCat-Next模型能听,能说。比如语音问答,或者让它用指定音色说话,能读能写(视觉理解和推理),还能画画和设计&#…...

Windows下Pytesseract报错‘Error opening data file’?三步搞定TESSDATA_PREFIX环境变量配置

Windows下Pytesseract报错终极解决方案:深入理解TESSDATA_PREFIX环境变量 每次看到屏幕上跳出那个令人沮丧的"Error opening data file"错误提示,我都忍不住想起自己第一次配置Pytesseract时的抓狂经历。作为一个长期与OCR打交道的开发者&…...

背包问题优化指南:从二维数组到一维数组的空间压缩技巧(以0-1背包为例)

背包问题优化指南:从二维数组到一维数组的空间压缩技巧(以0-1背包为例) 在算法竞赛和性能敏感的开发场景中,动态规划的空间复杂度优化往往能带来显著的性能提升。0-1背包问题作为动态规划的经典案例,其空间优化路径具…...

3大核心优势!Steamless开源工具链实现高效游戏文件DRM移除

3大核心优势!Steamless开源工具链实现高效游戏文件DRM移除 【免费下载链接】Steamless Steamless is a DRM remover of the SteamStub variants. The goal of Steamless is to make a single solution for unpacking all Steam DRM-packed files. Steamless aims to…...

如何快速完成黑苹果安装?OpCore Simplify终极简化指南

如何快速完成黑苹果安装?OpCore Simplify终极简化指南 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 厌倦了繁琐的黑苹果配置过程&#x…...

通义千问3-Reranker-0.6B效果展示:新闻标题-正文段落时效性重排案例

通义千问3-Reranker-0.6B效果展示:新闻标题-正文段落时效性重排案例 1. 引言:重排序技术的重要性 在信息爆炸的时代,我们每天都会接触到海量的新闻资讯。但你是否遇到过这样的情况:搜索一个热点事件,结果却出现大量过…...

PredRNN++:从单元到系统,逐层拆解与实战解析

1. PredRNN核心单元拆解 PredRNN作为视频预测领域的里程碑模型,其核心创新在于Causal LSTM和GHU两大单元的设计。我们先从代码层面看看它们如何运作。 1.1 Causal LSTM的三明治结构 打开CausalLSTMCell.py文件,你会发现这个单元像三明治一样分为三层&…...

mmdetection训练中断后如何精准恢复epoch?详解resume与配置文件调整

1. 理解训练中断恢复的核心逻辑 当你用mmdetection训练模型时,最崩溃的莫过于训练到第23个epoch突然断电。别慌,恢复训练的关键在于理解三个核心要素的联动关系: 检查点文件(.pth):保存了模型权重、优化器状态和当前epoch数--resu…...