Ai_GirlFriend/lover/deps.py

137 lines
5.2 KiB
Python
Raw Normal View History

2026-01-31 19:15:41 +08:00
from typing import Optional
import requests
from fastapi import Header, HTTPException, status, Cookie
from pydantic import BaseModel
from .config import settings
class AuthedUser(BaseModel):
id: int
reg_step: int = 1
gender: int = 0 # 0/1/2
nickname: str = ""
token: str = ""
def _fetch_user_from_php(token: str) -> Optional[dict]:
"""通过 PHP/FastAdmin 接口获取用户信息。"""
2026-02-02 20:08:28 +08:00
import logging
logger = logging.getLogger(__name__)
logger.info(f"用户中心调试 - 调用接口: {settings.USER_INFO_API}")
logger.info(f"用户中心调试 - token: {token}")
2026-01-31 19:15:41 +08:00
try:
resp = requests.get(
settings.USER_INFO_API,
headers={"token": token},
timeout=5,
)
2026-02-02 20:08:28 +08:00
logger.info(f"用户中心调试 - 响应状态码: {resp.status_code}")
logger.info(f"用户中心调试 - 响应内容: {resp.text[:200]}...")
2026-01-31 19:15:41 +08:00
except Exception as exc: # 网络/超时
2026-02-02 20:08:28 +08:00
logger.error(f"用户中心调试 - 请求异常: {exc}")
2026-01-31 19:15:41 +08:00
raise HTTPException(
status_code=status.HTTP_502_BAD_GATEWAY,
detail="用户中心接口不可用",
) from exc
if resp.status_code != 200:
2026-02-02 20:08:28 +08:00
logger.error(f"用户中心调试 - 状态码非200: {resp.status_code}")
2026-01-31 19:15:41 +08:00
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="用户中心返回非 200",
)
data = resp.json()
2026-02-02 20:08:28 +08:00
logger.info(f"用户中心调试 - 解析JSON成功: {data}")
2026-01-31 19:15:41 +08:00
# 兼容常见 FastAdmin 响应结构
if isinstance(data, dict):
payload = data.get("data") or data.get("user") or data
else:
payload = None
if not payload:
2026-02-02 20:08:28 +08:00
logger.error(f"用户中心调试 - 未找到用户数据: {data}")
2026-01-31 19:15:41 +08:00
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="用户中心未返回用户信息",
)
return payload
def get_current_user(
authorization: Optional[str] = Header(default=None),
x_token: Optional[str] = Header(default=None, alias="X-Token"),
token_header: Optional[str] = Header(default=None, alias="token"),
token_cookie: Optional[str] = Cookie(default=None, alias="token"),
x_user_id: Optional[int] = Header(default=None, alias="X-User-Id"),
):
"""
鉴权顺序
1) Authorization: Bearer <token>
2) X-Token: <token>
3) token: <token> (header)
4) token: <token> (cookie)
5) X-User-Id仅调试用不经过 PHP 鉴权
生产流程直接调用 USER_INFO_API 拉取用户信息不再依赖本地 nf_user 缓存
"""
import logging
logger = logging.getLogger(__name__)
logger.info(f"认证调试 - APP_ENV: {settings.APP_ENV}, DEBUG: {settings.DEBUG}")
logger.info(f"认证调试 - authorization: {authorization}, x_token: {x_token}, token_header: {token_header}, token_cookie: {token_cookie}, x_user_id: {x_user_id}")
token = None
if authorization and authorization.lower().startswith("bearer "):
token = authorization.split(" ", 1)[1].strip()
if not token and x_token:
token = x_token
if not token and token_header:
token = token_header
if not token and token_cookie:
token = token_cookie
logger.info(f"认证调试 - 提取的 token: {token}")
if token:
try:
payload = _fetch_user_from_php(token)
user_id = payload.get("id") or payload.get("user_id")
reg_step = payload.get("reg_step") or payload.get("stage") or 1
gender = payload.get("gender") or 0
nickname = payload.get("nickname") or payload.get("username") or ""
2026-02-01 10:03:21 +08:00
# 开发环境:自动提升 reg_step 到 2方便测试
if settings.APP_ENV == "development" and settings.DEBUG and reg_step < 2:
logger.warning(f"开发环境:用户 reg_step={reg_step},自动提升到 2")
reg_step = 2
2026-01-31 19:15:41 +08:00
if not user_id:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="用户中心缺少用户ID"
)
return AuthedUser(
id=user_id,
reg_step=reg_step,
gender=gender,
nickname=nickname,
token=token,
)
2026-02-01 10:03:21 +08:00
except HTTPException as e:
2026-01-31 19:15:41 +08:00
# 如果是开发环境token 验证失败时也返回测试用户
if settings.APP_ENV == "development" and settings.DEBUG:
2026-02-01 10:03:21 +08:00
logger.warning(f"开发环境token 验证失败({e.detail}),使用测试用户")
2026-02-02 20:08:28 +08:00
return AuthedUser(id=70, reg_step=2, gender=0, nickname="test-user", token="")
2026-02-01 10:03:21 +08:00
raise
2026-01-31 19:15:41 +08:00
# 调试兜底:仅凭 X-User-Id 不校验 PHP方便联调
if x_user_id is not None:
return AuthedUser(id=x_user_id, reg_step=2, gender=0, nickname="debug-user", token="")
# 开发环境兜底:如果没有任何认证信息,返回默认测试用户
if settings.APP_ENV == "development" and settings.DEBUG:
2026-02-02 20:08:28 +08:00
return AuthedUser(id=70, reg_step=2, gender=0, nickname="test-user", token="")
2026-01-31 19:15:41 +08:00
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户不存在或未授权")