This commit is contained in:
dekun
2026-05-30 16:01:35 +08:00
parent 979054546c
commit cdbe087202
6 changed files with 235 additions and 20 deletions
+38
View File
@@ -187,11 +187,19 @@ def create_app(settings: Settings) -> FastAPI:
if str(_root) not in sys.path:
sys.path.insert(0, str(_root))
from nav_embed import install_nav_embed, nav_session_middleware_kwargs
from nav_session_auth import (
create_embed_bootstrap_token,
nav_embed_session_active,
safe_next_path,
)
install_nav_embed(app)
_sess_kw = nav_session_middleware_kwargs()
except Exception:
_sess_kw = {"same_site": "lax", "https_only": False}
nav_embed_session_active = lambda: False # type: ignore
create_embed_bootstrap_token = None # type: ignore
safe_next_path = lambda raw=None: "/dashboard" # type: ignore
app.add_middleware(GZipMiddleware, minimum_size=800)
app.add_middleware(
SessionMiddleware,
@@ -329,14 +337,44 @@ def create_app(settings: Settings) -> FastAPI:
return JSONResponse({"ok": False, "detail": "请求格式错误"}, status_code=400)
username = str(body.get("username") or "").strip()
password = str(body.get("password") or "")
embed = (request.headers.get("x-nav-embed") or "").strip() == "1" or str(
body.get("embed") or ""
).strip().lower() in ("1", "true", "yes")
ok_user = username == app.state.auth_user
ok_pass = _hash_password(password) == app.state.auth_password_hash
if ok_user and ok_pass:
request.session["logged_in"] = True
request.session["username"] = username
if embed or nav_embed_session_active():
from urllib.parse import urlencode
nxt = safe_next_path(str(body.get("next") or "/dashboard"))
boot = create_embed_bootstrap_token(username, secret=settings.app.session_secret)
q = urlencode({"token": boot, "next": nxt, "embed": "1"})
return JSONResponse(
{
"ok": True,
"redirect": nxt,
"session_token": boot,
"embed_auth_url": f"/embed-auth?{q}",
}
)
return JSONResponse({"ok": True, "redirect": "/dashboard"})
return JSONResponse({"ok": False, "detail": "用户名或密码错误"}, status_code=401)
@app.get("/embed-auth")
async def embed_auth(request: Request, token: str = "", next: str = "/dashboard") -> RedirectResponse:
from nav_session_auth import safe_next_path, validate_embed_bootstrap_token
if not settings.auth.enabled:
return RedirectResponse(safe_next_path(next), status_code=302)
ok, username = validate_embed_bootstrap_token(token, secret=settings.app.session_secret)
if ok:
request.session["logged_in"] = True
request.session["username"] = username or settings.auth.username
return RedirectResponse(safe_next_path(next), status_code=302)
return RedirectResponse("/login?embed=1", status_code=302)
@app.get("/logout")
async def logout(request: Request) -> RedirectResponse:
request.session.clear()
+10 -3
View File
@@ -51,6 +51,7 @@
body: JSON.stringify({
username: fd.get("username"),
password: fd.get("password"),
embed: window.self !== window.top ? "1" : "0",
}),
})
.then(function (r) {
@@ -59,9 +60,15 @@
});
})
.then(function (x) {
if (x.ok && x.body && x.body.redirect) {
window.location.href = x.body.redirect;
return;
if (x.ok && x.body) {
var dest =
window.self !== window.top && x.body.embed_auth_url
? x.body.embed_auth_url
: x.body.redirect || "/dashboard";
if (dest) {
window.location.href = dest;
return;
}
}
if (errEl) {
errEl.textContent = (x.body && x.body.detail) || "登录失败";