fix: session cookie options for HTTP (insecure override + auto secure)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-05-12 16:02:50 +08:00
parent 9632b91e70
commit 03a5a43f30
2 changed files with 41 additions and 5 deletions
+6 -2
View File
@@ -26,7 +26,11 @@
# 在 Nginx/Caddy 等反向代理后部署时:信任 X-Forwarded-*,以便 Cookie、CSRF 与 HTTPS 判断正确
# NAV_TRUST_PROXY=1
# 站点仅通过 https:// 对外访问时建议开启;若用 http://内网IP:端口 访问请勿开启,否则浏览器不保存登录 Cookie
# NAV_SESSION_COOKIE_SECURE=1
# 会话 Cookie 的 Secure 标志(与浏览器地址栏是否 https 一致才有效):
# - 内网用 http://IP:端口:不要写 NAV_SESSION_COOKIE_SECURE=1;或保留 1 时另加 NAV_COOKIES_INSECURE_HTTP=1 强制关闭 Secure
# - 纯 https 对外:NAV_SESSION_COOKIE_SECURE=1
# - 反代后同时有 http/https:可试 NAV_SESSION_COOKIE_SECURE=auto(并配合 NAV_TRUST_PROXY=1
# NAV_COOKIES_INSECURE_HTTP=1
# NAV_SESSION_COOKIE_SECURE=auto
# CSRF 校验仍失败时,可填前端访问的完整 Origin,多个用英文逗号分隔,例如:
# NAV_CSRF_TRUSTED_ORIGINS=https://nav.example.com
+35 -3
View File
@@ -55,6 +55,40 @@ login_manager = LoginManager()
csrf = CSRFProtect()
def _apply_session_cookie_settings(app: Flask) -> None:
"""Secure Cookie 仅在浏览器用 https:// 访问时才有意义;用 http://IP:端口 时若仍设 Secure,浏览器会丢弃会话,表现为登录后立即回到登录页。"""
if os.environ.get("NAV_COOKIES_INSECURE_HTTP") == "1":
app.config["SESSION_COOKIE_SECURE"] = False
app.config["REMEMBER_COOKIE_SECURE"] = False
if (os.environ.get("NAV_SESSION_COOKIE_SECURE") or "").strip().lower() in (
"1",
"true",
"yes",
):
print(
"[nav] NAV_COOKIES_INSECURE_HTTP=1:已关闭 Secure Cookie,便于 http:// 内网访问。",
flush=True,
)
return
mode = (os.environ.get("NAV_SESSION_COOKIE_SECURE") or "0").strip().lower()
if mode in ("1", "true", "yes"):
app.config["SESSION_COOKIE_SECURE"] = True
app.config["REMEMBER_COOKIE_SECURE"] = True
elif mode == "auto":
app.config["SESSION_COOKIE_SECURE"] = False
app.config["REMEMBER_COOKIE_SECURE"] = False
@app.before_request
def _nav_session_cookie_secure_auto():
sec = request.is_secure
app.config["SESSION_COOKIE_SECURE"] = sec
app.config["REMEMBER_COOKIE_SECURE"] = sec
else:
app.config["SESSION_COOKIE_SECURE"] = False
app.config["REMEMBER_COOKIE_SECURE"] = False
def create_app() -> Flask:
app = Flask(__name__)
app.config["SECRET_KEY"] = os.environ.get("NAV_SECRET_KEY") or secrets.token_hex(32)
@@ -64,9 +98,7 @@ def create_app() -> Flask:
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["WTF_CSRF_TIME_LIMIT"] = None
if os.environ.get("NAV_SESSION_COOKIE_SECURE") == "1":
app.config["SESSION_COOKIE_SECURE"] = True
app.config["REMEMBER_COOKIE_SECURE"] = True
_apply_session_cookie_settings(app)
trusted = os.environ.get("NAV_CSRF_TRUSTED_ORIGINS", "").strip()
if trusted: