From 9525dadfd6e8345f76fd85c7d3b79d037f265753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=93=E9=9B=A8=E9=B9=8F?= <846149189@qq.com> Date: Sat, 13 Jun 2026 11:39:05 +0800 Subject: [PATCH] =?UTF-8?q?feat(auth):=20=E5=8A=A0=20STORY=5FWEB=5FNO=5FAU?= =?UTF-8?q?TH=20=E6=9C=AC=E5=9C=B0=E5=85=8D=E9=89=B4=E6=9D=83=E5=BC=80?= =?UTF-8?q?=E5=85=B3(=E9=BB=98=E8=AE=A4=E5=85=B3,=E7=BA=BF=E4=B8=8A?= =?UTF-8?q?=E4=B8=8D=E5=8F=97=E5=BD=B1=E5=93=8D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 设 STORY_WEB_NO_AUTH=1 时跳过登录、署名记「本地」、不校验 STORY_WEB_USERS——仅本地开发用。 线上不设此变量 → 行为完全不变,照常每人一把口令(安全设计未动)。 --- web/app.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/web/app.py b/web/app.py index c14b4ff..ac6b70d 100644 --- a/web/app.py +++ b/web/app.py @@ -39,6 +39,10 @@ _STATIC_DIR = os.path.join(_HERE, "static") COOKIE = "story_auth" SESSION_DAYS = 30 +# 免鉴权开关:仅本地开发用。设 STORY_WEB_NO_AUTH=1 时跳过登录(不要在线上设)。 +# 线上不设此变量 → 行为不变,照常要口令。 +NO_AUTH = (os.environ.get("STORY_WEB_NO_AUTH") or "").strip().lower() in ("1", "true", "yes", "on") + def _load_users(): """解析 STORY_WEB_USERS="名字1:口令1,名字2:口令2"。返回 {口令: 名字}。 @@ -46,6 +50,8 @@ def _load_users(): 未配置/格式错/口令过短/口令重复 → 直接拒绝启动(宁可起不来,不可弱口令裸奔)。 口令即身份:登录只输口令,服务端按口令认人,updated_by 由服务端填写。 """ + if NO_AUTH: + return {} # 免鉴权模式(仅本地):无需口令,不校验 STORY_WEB_USERS raw = (os.environ.get("STORY_WEB_USERS") or "").strip() if not raw: sys.exit('[story-web] 未配置 STORY_WEB_USERS,拒绝启动。' @@ -101,6 +107,9 @@ def _session_user(request): @app.middleware("http") async def auth_guard(request: Request, call_next): path = request.url.path + if NO_AUTH: # 本地免鉴权:全部放行,署名记为「本地」 + request.state.user = "本地" + return await call_next(request) # 放行登录、静态资源、根 if path.startswith("/api/") and path != "/api/login": user = _session_user(request)