fix: session cookie options for HTTP (insecure override + auto secure)
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+6
-2
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user