feat(fam-edge): 统一登录从 NAS fam-core 迁入,回调失败不再对跳死循环

登录入口原先跑在 NAS 的 fam-core 里,NAS 或 frp 隧道一挂,
smart-camera.zichuan.xyz/login 直接 502——连登录页都打不开。登录是入口,
不该依赖家里那台机器,整体搬到甲骨文(前端静态文件和 auth-hub 本来就在这台)。

跟旧实现的三处关键差异:
- 换 token / 拉 JWKS 走 AUTH_HUB_INTERNAL_BASE(本机 :5300),不再跨公网 TLS。
  旧链路上 PyJWKClient 用 urllib + 系统 CA(群晖易 CERTIFICATE_VERIFY_FAILED)、
  两机时钟偏差会让 iat 显得来自未来,这两个坑一起消失;iss 校验和浏览器跳转
  仍用公网 issuer
- 会话改无状态 HS256 签名 cookie,服务重启不掉线(旧实现是进程内 token 表)
- 回调失败渲染错误页,不再 302 回 /login。旧实现失败即跳 /login,而 auth-hub
  只要还有会话就立刻再签一个 code 跳回来,两边对跳成死循环,浏览器只报
  「重定向次数过多」,既看不到登录页也看不到原因

fam-core 侧删除 auth.py 与 test_auth.py,鉴权改由甲骨文 Caddy 的 forward_auth
前置拦截(打 /api/auth/verify)。

测试:fam-edge 新增 16 个用例,含「失败分支绝不 302」回归测试、
「服务端走内网但 iss 按公网校验」、「cookie 无状态」。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
ericwyuan
2026-09-13 08:02:59 +08:00
parent 0238030128
commit dc284f4bf5
6 changed files with 533 additions and 541 deletions

View File

@@ -2,6 +2,9 @@ flask>=2.0.0
gunicorn>=20.0.0
requests>=2.28.0
PyYAML>=6.0
# 统一登录:验 auth-hub 的 id_token 签名RS256+ 签发会话 cookieHS256
PyJWT>=2.8.0
cryptography>=42.0.0
# google-generativeai 和 openai 为可选依赖(代码用 requests 直接调 REST API
# 如需 SDK 方式调用,取消注释并在 Python 3.9+ 环境安装:
# google-generativeai>=0.5.0