跳转至

后端-认证-cron任务401写入失败

问题现象

  • "获取记录"页面看不到当天的日报记录
  • daily_crawl.py cron 任务日志显示 "报告已写入数据库",但实际 fetch_records 表中无数据
  • 系统日志中 POST /api/fetch-records 返回 401 Unauthorized

核心问题

根因 1:AuthMiddleware 拦截内部 cron 调用 - AuthMiddleware 对所有 /api/* 请求(白名单外)要求 JWT 认证 - daily_crawl.py 通过 requests.post("http://localhost:8000/api/fetch-records") 调用,不携带 Authorization: Bearer 头 - 中间件返回 401,数据库写入未执行

根因 2:daily_crawl.py 未检查 HTTP 状态码 - requests.post() 只捕获网络异常,不检查 HTTP 状态码 - 401 被静默吞掉,脚本打印 "报告已写入数据库"(误报成功)

解决方法

步骤 1:在 auth_middleware.py 中放行 localhost

# 在 JWT 校验之前增加:
client_host = request.client.host if request.client else None
if client_host in ("127.0.0.1", "::1"):
    return await call_next(request)

步骤 2:在 daily_crawl.py 中检查状态码

resp = requests.post("http://localhost:8000/api/fetch-records", ...)
if resp.status_code == 201:
    logger.info("报告已写入数据库")
else:
    logger.warning("写入数据库失败 | status=%d | response=%s", resp.status_code, resp.text[:200])

步骤 3:部署

# 本地提交
git add src/core/auth_middleware.py scripts/daily_crawl.py
git commit -m "fix: cron 任务因认证 401 无法写入获取记录"
git -c http.proxy= -c https.proxy= push origin main

# 服务器部署
ssh news "cd /www/news && git pull origin main && systemctl restart news-backend"

步骤 4:验证

ssh news "curl -s -X POST http://localhost:8000/api/fetch-records \
  -H 'Content-Type: application/json' \
  -d '{\"record_date\":\"2026-07-02\",\"content\":\"# 验证测试\"}'"
# 预期返回: {"code":0,"message":"创建成功"}

下次防错措施

  • 快速定位:查看 /www/news/log/daily_crawl.log 末尾是否有 status=401 或缺少 "报告已写入数据库"
  • 系统日志验证ssh news "journalctl -u news-backend --since 'today' | grep fetch-records"
  • 巡检脚本:可在定时任务中增加 curl 检查 POST /api/fetch-records 返回是否包含 "code":0
  • 流程改进:所有内部 HTTP 调用 requests.post() 应检查状态码,不能只捕获异常