修复登录
This commit is contained in:
@@ -25,7 +25,7 @@ HUB_TRUST_LAN=true
|
||||
# HUB_PASSWORD=your-strong-password-here
|
||||
# 会话签名密钥(建议单独随机串;未设则用用户名+密码拼接)
|
||||
# HUB_SESSION_SECRET=another-long-random-string
|
||||
# HTTPS 反代时设为 true,Cookie 仅通过加密连接传输
|
||||
# HTTPS 反代时建议 true:仅 HTTPS 访问会带 Secure Cookie;http://内网IP:5100 仍可登录
|
||||
# HUB_COOKIE_SECURE=true
|
||||
# 登录保持天数(默认 7)
|
||||
# HUB_SESSION_DAYS=7
|
||||
|
||||
@@ -23,7 +23,7 @@ from settings_store import (
|
||||
from hub_web_auth import (
|
||||
SESSION_COOKIE,
|
||||
SESSION_MAX_AGE_SEC,
|
||||
cookie_secure,
|
||||
cookie_secure_for_request,
|
||||
create_session_token,
|
||||
is_public_path,
|
||||
password_required,
|
||||
@@ -160,12 +160,13 @@ def api_auth_status(request: Request):
|
||||
|
||||
|
||||
@app.post("/api/auth/login")
|
||||
def api_auth_login(body: LoginBody):
|
||||
def api_auth_login(body: LoginBody, request: Request):
|
||||
if not password_required():
|
||||
return {"ok": True, "auth_disabled": True}
|
||||
if not verify_credentials(body.username, body.password):
|
||||
raise HTTPException(status_code=401, detail="用户名或密码错误")
|
||||
token = create_session_token(body.username)
|
||||
secure = cookie_secure_for_request(request)
|
||||
resp = JSONResponse({"ok": True})
|
||||
resp.set_cookie(
|
||||
SESSION_COOKIE,
|
||||
@@ -174,15 +175,16 @@ def api_auth_login(body: LoginBody):
|
||||
samesite="lax",
|
||||
path="/",
|
||||
max_age=SESSION_MAX_AGE_SEC,
|
||||
secure=cookie_secure(),
|
||||
secure=secure,
|
||||
)
|
||||
return resp
|
||||
|
||||
|
||||
@app.post("/api/auth/logout")
|
||||
def api_auth_logout():
|
||||
def api_auth_logout(request: Request):
|
||||
secure = cookie_secure_for_request(request)
|
||||
resp = JSONResponse({"ok": True})
|
||||
resp.delete_cookie(SESSION_COOKIE, path="/")
|
||||
resp.delete_cookie(SESSION_COOKIE, path="/", secure=secure)
|
||||
return resp
|
||||
|
||||
|
||||
|
||||
@@ -92,8 +92,30 @@ def validate_session_token(token: str | None) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def cookie_secure() -> bool:
|
||||
return (os.getenv("HUB_COOKIE_SECURE") or "").strip().lower() in ("1", "true", "yes", "on")
|
||||
def cookie_secure_env_enabled() -> bool:
|
||||
"""是否在 .env 中启用「HTTPS 时带 Secure Cookie」策略。"""
|
||||
return (os.getenv("HUB_COOKIE_SECURE") or "").strip().lower() in (
|
||||
"1",
|
||||
"true",
|
||||
"yes",
|
||||
"on",
|
||||
)
|
||||
|
||||
|
||||
def cookie_secure_for_request(request) -> bool:
|
||||
"""
|
||||
仅在实际 HTTPS 访问时设置 Secure Cookie。
|
||||
这样可同时支持:域名 HTTPS 反代 + 内网 http://IP:5100 登录。
|
||||
"""
|
||||
if not cookie_secure_env_enabled():
|
||||
return False
|
||||
proto = (
|
||||
(request.headers.get("x-forwarded-proto") or request.url.scheme or "http")
|
||||
.split(",")[0]
|
||||
.strip()
|
||||
.lower()
|
||||
)
|
||||
return proto == "https"
|
||||
|
||||
|
||||
def is_public_path(path: str, method: str) -> bool:
|
||||
|
||||
@@ -277,7 +277,8 @@ python hub.py
|
||||
| 无关键位块 | 该户 capabilities 无 `key` | 正常;Gate 趋势户无关键位 |
|
||||
| 局域网无法打开中控 | 防火墙 / `HUB_TRUST_LAN=0` | 放行端口或恢复默认信任私网 |
|
||||
| 打开即跳转登录 | 已设 `HUB_PASSWORD` | 正常;输入密码后 7 天内免登(可改 `HUB_SESSION_DAYS`) |
|
||||
| 登录后仍 401 | Cookie 未带上 / HTTPS | HTTPS 反代设 `HUB_COOKIE_SECURE=true` |
|
||||
| 域名能登录、IP:5100 不能 | `HUB_COOKIE_SECURE=true` 且用 http 访问 IP | 已改为仅 HTTPS 才发 Secure Cookie;或 IP 用 http、域名用 https 各登一次 |
|
||||
| 登录后仍 401 | Cookie 未带上 | 反代需传 `X-Forwarded-Proto: https`;勿混用不同主机名的 Cookie |
|
||||
|
||||
手动探测实例桥接:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user