50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
API 公共依赖:认证校验、请求体解析。
|
|
所有路由文件统一从这里导入,避免重复代码。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from fastapi import Cookie, HTTPException, Request, status
|
|
|
|
from server import db
|
|
|
|
|
|
# ────────────────────────── 认证依赖 ──────────────────────────
|
|
|
|
async def require_auth(auth_token: str | None = Cookie(default=None)):
|
|
"""
|
|
从 cookie 中读取 auth_token 并校验。
|
|
用法:在 Router 或单个接口上加 dependencies=[Depends(require_auth)]
|
|
"""
|
|
if auth_token is None:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="未登录,请先调用 POST /api/auth/login",
|
|
)
|
|
user = db.get_user_by_token(auth_token)
|
|
if not user:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="登录已失效,请重新登录",
|
|
)
|
|
return user
|
|
|
|
|
|
# ────────────────────────── 请求体解析 ──────────────────────────
|
|
|
|
async def parse_body(request: Request) -> dict:
|
|
"""
|
|
兼容两种请求体格式:
|
|
1) application/json
|
|
2) multipart/form-data 或 x-www-form-urlencoded
|
|
"""
|
|
ctype = (request.headers.get("content-type") or "").lower()
|
|
if "application/json" in ctype:
|
|
data = await request.json()
|
|
if not isinstance(data, dict):
|
|
raise HTTPException(status_code=422, detail="JSON body 必须是对象")
|
|
return data
|
|
form = await request.form()
|
|
return dict(form)
|