v0.1.0: CRM/ERP 系统内测版本 - 安全加固完成

- Docker bridge 网络隔离(8000 端口封死)
- Gunicorn 4 Worker 多进程
- Alembic 数据库迁移基线
- 日志轮转 20m×3
- JWT 密钥 + DB 密码 + CORS 收紧
- 3-2-1 备份链路(NAS + R740-B 冷备)
- 连接池 pool_pre_ping + pool_recycle=3600
This commit is contained in:
hankin
2026-03-16 07:31:37 +00:00
commit 423baff73b
2578 changed files with 824643 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
"""
FastAPI 依赖注入 —— 权限拦截核心
get_current_user: 解析 JWT → 查表获取完整权限上下文
"""
from __future__ import annotations
from fastapi import Depends, Header
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.exceptions import UnauthorizedException
from app.core.security import decode_access_token
from app.db.database import get_db
from app.models.sys import SysUser
from app.schemas.auth import CurrentUserPayload
async def get_current_user(
authorization: str = Header(..., description="Bearer <token>"),
db: AsyncSession = Depends(get_db),
) -> CurrentUserPayload:
"""
核心鉴权依赖:
1. 从 Header 提取 Bearer Token
2. 解码 JWT 拿到 user_id
3. 查 sys_users + 联表 role/dept 拿到 data_scope 等完整上下文
4. 返回 CurrentUserPayload 供业务层使用
"""
# ── 解析 Bearer Token ──
if not authorization.startswith("Bearer "):
raise UnauthorizedException("Authorization 格式错误,需为 Bearer <token>")
token = authorization.removeprefix("Bearer ").strip()
payload = decode_access_token(token)
if payload is None:
raise UnauthorizedException("Token 无效或已过期")
user_id: str | None = payload.get("sub")
if user_id is None:
raise UnauthorizedException("Token 载荷缺少 sub 字段")
# ── 查库获取用户及关联角色 ──
stmt = (
select(SysUser)
.where(SysUser.id == user_id, SysUser.is_deleted.is_(False))
)
result = await db.execute(stmt)
user = result.scalar_one_or_none()
if user is None:
raise UnauthorizedException("用户不存在或已被停用")
if user.status != 1:
raise UnauthorizedException("账号已被禁用")
# ── 组装权限上下文 ──
return CurrentUserPayload(
user_id=user.id,
username=user.username,
real_name=user.real_name,
dept_id=user.dept_id,
dept_name=user.department.name if user.department else None,
role_id=user.role_id,
role_name=user.role.role_name if user.role else None,
data_scope=user.role.data_scope if user.role else "self",
menu_keys=user.role.menu_keys if user.role else [],
)