dingdanquanliucheng/backend/app/api/deps.py

157 lines
5.7 KiB
Python
Raw Normal View History

"""
API 依赖注入模块
职责
提供 FastAPI Depends 依赖函数供各路由文件使用包括
- get_current_user从请求头提取并验证 JWT 令牌返回当前登录用户
- require_roles角色鉴权仅允许指定角色访问接口
- require_permissions权限鉴权仅拥有指定权限码的用户可访问
- 各业务服务的工厂函数get_order_service 用于解耦路由与服务实例化
"""
2026-06-15 13:18:43 +08:00
from fastapi import Depends, Header, Response
from sqlalchemy.orm import Session
from backend.app.core.error_codes import ErrorCode
from backend.app.core.exceptions import AppException
2026-06-15 13:18:43 +08:00
from backend.app.core.security import should_refresh_token, create_access_token
from backend.app.db import get_db_session
2026-05-14 13:51:06 +08:00
from backend.app.services.audit_service import audit_service
from backend.app.services.auth_service import auth_service
from backend.app.services.config_service import config_service
from backend.app.services.customer_service import customer_service
from backend.app.services.logistics_service import logistics_service
from backend.app.services.order_service import order_service
from backend.app.services.product_service import product_service
from backend.app.services.reminder_service import reminder_service
from backend.app.services.report_service import report_service
from backend.app.services.supplier_service import supplier_service
from backend.app.services.system_service import system_service
2026-05-26 17:20:21 +08:00
from backend.app.services.ai_service import ai_service
2026-05-14 13:51:06 +08:00
# 统一依赖入口,后续如果切换到真实容器或数据库实现,只需要改这里。
def get_auth_service():
"""获取认证服务实例"""
2026-05-14 13:51:06 +08:00
return auth_service
def get_current_user(
2026-06-15 13:18:43 +08:00
response: Response, # FastAPI Response 对象,用于设置响应头
authorization: str | None = Header(default=None), # 请求头中的 Authorization 字段,格式为 "Bearer <token>"
auth_service=Depends(get_auth_service), # 注入认证服务实例
session: Session = Depends(get_db_session), # 注入数据库会话
) -> dict:
"""从请求头解析 JWT 令牌并获取当前登录用户
用途所有需要认证的接口通过 Depends(get_current_user) 调用
请求参数通过请求头 Authorization 传递 Bearer Token
返回值当前用户信息字典包含 user_idrole_codepermissions
权限要求必须携带有效的 JWT 令牌
2026-06-15 13:18:43 +08:00
特性 Token 剩余有效期不足 30 天时自动续期并通过响应头 X-New-Token 返回新 Token
"""
token = (authorization or "").removeprefix("Bearer").strip()
user = auth_service.get_me(token, session)
if not user:
raise AppException(code=ErrorCode.UNAUTHORIZED, message="未登录或登录失效", status_code=401)
2026-06-15 13:18:43 +08:00
# 滑动过期Token 剩余不足 30 天时自动续期
if should_refresh_token(token, threshold_days=30):
new_token = create_access_token({
"user_id": user["user_id"],
"role_code": user["role_code"],
})
response.headers["X-New-Token"] = new_token
return user
def require_roles(*role_codes: str):
"""角色鉴权工厂函数
用途返回一个依赖函数校验当前用户的角色是否在允许列表中
参数*role_codes - 允许访问的角色编码列表 "admin""manager""salesman"
返回值当前用户信息字典角色校验通过时
权限要求当前用户的角色编码必须属于 role_codes 之一
"""
def _require_roles(current_user: dict = Depends(get_current_user)) -> dict:
if role_codes and current_user.get("role_code") not in role_codes:
raise AppException(code=ErrorCode.FORBIDDEN, message="无权限访问", status_code=403)
return current_user
return _require_roles
def require_permissions(*permission_codes: str):
"""权限鉴权工厂函数
用途返回一个依赖函数校验当前用户是否拥有指定权限码
参数*permission_codes - 所需权限码列表 "order:list""order:create"
返回值当前用户信息字典权限校验通过时
权限要求当前用户的 permissions 列表必须包含所有指定的权限码
"""
def _require_permissions(current_user: dict = Depends(get_current_user)) -> dict:
if not permission_codes:
return current_user
granted = set(current_user.get("permissions") or [])
missing = [code for code in permission_codes if code not in granted]
if missing:
raise AppException(code=ErrorCode.FORBIDDEN, message="缺少必要权限", status_code=403)
return current_user
return _require_permissions
2026-05-14 13:51:06 +08:00
def get_order_service():
"""获取订单服务实例"""
2026-05-14 13:51:06 +08:00
return order_service
def get_customer_service():
"""获取客户服务实例"""
2026-05-14 13:51:06 +08:00
return customer_service
def get_product_service():
"""获取产品服务实例"""
2026-05-14 13:51:06 +08:00
return product_service
def get_logistics_service():
"""获取物流服务实例"""
2026-05-14 13:51:06 +08:00
return logistics_service
def get_supplier_service():
"""获取供应商服务实例"""
2026-05-14 13:51:06 +08:00
return supplier_service
def get_reminder_service():
"""获取提醒服务实例"""
2026-05-14 13:51:06 +08:00
return reminder_service
def get_report_service():
"""获取报表服务实例"""
2026-05-14 13:51:06 +08:00
return report_service
def get_config_service():
"""获取配置服务实例"""
2026-05-14 13:51:06 +08:00
return config_service
def get_audit_service():
"""获取审计日志服务实例"""
2026-05-14 13:51:06 +08:00
return audit_service
def get_system_service():
"""获取系统服务实例"""
return system_service
2026-05-26 17:20:21 +08:00
def get_ai_service():
"""获取 AI 服务实例"""
2026-05-26 17:20:21 +08:00
return ai_service