FastAPI 角色權(quán)限管理(RBAC):入門級思路
作者:Ss肥魚
本篇文章將手把手教你如何在 FastAPI 中 實現(xiàn)角色權(quán)限系統(tǒng),實現(xiàn)真正的多用戶訪問控制!
- 你是否想讓管理員擁有更多權(quán)限?
- 普通用戶只能訪問自己的內(nèi)容?
RBAC(基于角色的訪問控制)是解決多角色權(quán)限管理的最佳實踐。本篇文章將手把手教你如何在 FastAPI 中 實現(xiàn)角色權(quán)限系統(tǒng),實現(xiàn)真正的多用戶訪問控制!
什么是 RBAC?
RBAC(Role-Based Access Control)是一種 通過角色(Role)管理權(quán)限(Permission) 的模型:
- 用戶(User) → 屬于一個或多個角色
- 角色(Role) → 擁有若干權(quán)限
- 權(quán)限(Permission) → 授權(quán)訪問接口、資源
好處:
- 權(quán)限解耦:權(quán)限不直接綁定用戶,而是抽象為角色
- 擴(kuò)展性強(qiáng):修改權(quán)限只需更新角色
- 更安全、更規(guī)范
目錄結(jié)構(gòu)示例
app/
├── api/
│ └── user.py
├── auth/
│ ├── auth.py # 登錄認(rèn)證
│ └── deps.py # 權(quán)限控制邏輯
├── core/
│ └── security.py
├── models/
│ ├── user.py # 用戶模型
│ └── role.py # 角色模型
├── schemas/
│ ├── user.py
│ └── role.py
用戶與角色模型定義
models/role.py:
from tortoise.models import Model
from tortoise import fields
class Role(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=50, unique=True)
users: fields.ReverseRelation["User"]
models/user.py:
from tortoise.models import Model
from tortoise import fields
from .role import Role
class User(Model):
id = fields.IntField(pk=True)
username = fields.CharField(max_length=50, unique=True)
hashed_password = fields.CharField(max_length=128)
role = fields.ForeignKeyField("models.Role", related_name="users")
用戶注冊默認(rèn)賦予角色
api/user.py:
@router.post("/register", response_model=UserOut)
async def register(user: UserCreate):
default_role = await Role.get_or_create(name="user") # 默認(rèn)角色
hashed_pwd = hash_password(user.password)
role_obj, created = await Role.get_or_create(name="user")
new_user = await User.create(
username=user.username,
hashed_password=hashed_pwd,
role=role_obj
)
return new_user
權(quán)限控制依賴(auth/deps.py)
我們新增一個 require_role 方法來檢查用戶的角色:
from fastapi import Depends, HTTPException
from app.auth.auth import oauth2_scheme
from jose import jwt, JWTError
from app.models.user import User
from app.core.security import SECRET_KEY, ALGORITHM
asyncdefget_current_user(token: str = Depends(oauth2_scheme)):
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username = payload.get("sub")
except JWTError:
raise HTTPException(status_code=401, detail="Token 認(rèn)證失敗")
user = await User.get_or_none(username=username).prefetch_related("role")
ifnot user:
raise HTTPException(status_code=404, detail="用戶不存在")
return user
defrequire_role(required_roles: list[str]):
asyncdefchecker(current_user: User = Depends(get_current_user)):
if current_user.role.name notin required_roles:
raise HTTPException(status_code=403, detail="權(quán)限不足")
return current_user
return checker
使用示例:不同接口設(shè)定權(quán)限
@router.get("/admin-only")
async def admin_route(current_user=Depends(require_role(["admin"]))):
return {"msg": f"歡迎管理員 {current_user.username}"}
@router.get("/user")
async def user_route(current_user=Depends(require_role(["user", "admin"]))):
return {"msg": f"歡迎用戶 {current_user.username}"}
擴(kuò)展建議(可選)
- 增加 Permission 表:實現(xiàn)更細(xì)粒度控制(如資源級權(quán)限)
- 支持 多角色綁定:用戶擁有多個角色(ManyToMany)
- 引入 菜單/接口授權(quán)系統(tǒng):可視化配置權(quán)限
- 添加 RBAC 管理后臺界面
總結(jié)
通過本文你實現(xiàn)了:
- 用戶 ?? 角色 ?? 權(quán)限 的完整閉環(huán)
- FastAPI 中的 權(quán)限依賴注入
- 管理員/用戶等不同訪問控制場景
責(zé)任編輯:趙寧寧
來源:
Ssoul肥魚