Files
FinDataHub cb11a3d445 fix(backend): API_KEY 统一从持久化文件加载,修掉受保护端点恒 401
## 现象

装机后测受保护端点,文件 key → 401、乱码 key → 401、无 key → 401。
全 401 说明不是「没鉴权」,而是**鉴权用的 key 与客户端手里的不是同一个**。

## 根因(与 T6 同族,又一处双入口分叉)

  app/main.py                      → _load_or_create_api_key()   读持久化文件
  Scripts/bin/newsflash_backend.py → secrets.token_urlsafe(32)   现生成随机值

生产走后者,每次启动换一把钥匙。客户端读 ~/Library/Application Support/
findatahub/.api_key 去请求,永远对不上;两边都不报错,只表现为「点了没反应」。

## 修复

把加载逻辑收进 app/dependencies.py::load_or_create_api_key(),两个入口共用:

- 文件已存在 → 复用,**不覆盖**(覆盖会让客户端手里的旧 key 立即失效)
- 文件存在但内容为空 → 补生成(空 key 会让 compare_digest("", "") 恒真)

路径用 platformdirs.user_config_dir("findatahub"),macOS 上即
~/Library/Application Support/findatahub,与 Swift 端读取位置一致。

## 部署位实测

  文件 key → HTTP 200   (修复前 401)
  乱码 key → HTTP 401
  无 key   → HTTP 401

## 防回退锁

test_app_factory.py::TestApiKeySource 3 条:共享加载函数存在、复用时不被覆盖/
空内容补生成、两个入口源码都必须出现 load_or_create_api_key 且都不得出现
secrets.token_urlsafe。

backend 443 → 446。

## 这一族的教训

T6 收敛了「装配」,但 lifespan 里还藏着同类分叉。凡是「两个入口都该有且必须一致」
的逻辑,都该像 key 加载这样收成单一函数,而不是指望两边同步。
2026-10-27 23:23:06 +08:00
..