fix: refine auth cookie and route redirects

This commit is contained in:
chengkml
2026-05-17 00:09:33 +08:00
parent 5cf82f3468
commit 4074f597c4
5 changed files with 76 additions and 23 deletions
+1
View File
@@ -566,6 +566,7 @@
- 未登录访问后台时提示“前往登录”(`/login`);
- 账号菜单提供“用户管理”(`/users`)作为默认后台入口。
- 退出登录口径:统一跳转到登录页 `/login`(不保留在当前后台路由)。
- 宿主机 Nginx 的 `location = /fl` 不要再重定向到 `/fl/`;在 `basePath=/fl` 下,这会和 Next 的路径归一逻辑相互打架。当前口径是把 `/fl` 直接导向 `/fl/login`,并在改完 `quiz.conf` 后立即 `nginx -t && nginx -s reload`
## 站点标题口径(2026-04-24
+21 -8
View File
@@ -28,24 +28,37 @@ def _client_ip(request: Request) -> str | None:
return None
def _set_refresh_cookie(response: Response, token: str) -> None:
def _is_secure_request(request: Request) -> bool:
forwarded_proto = request.headers.get("x-forwarded-proto")
if forwarded_proto:
return forwarded_proto.split(",")[0].strip().lower() == "https"
return request.url.scheme == "https"
def _refresh_cookie_secure(request: Request) -> bool:
if not settings.refresh_cookie_secure:
return False
return _is_secure_request(request)
def _set_refresh_cookie(request: Request, response: Response, token: str) -> None:
response.set_cookie(
key=settings.refresh_cookie_name,
value=token,
httponly=True,
secure=settings.refresh_cookie_secure,
secure=_refresh_cookie_secure(request),
samesite=settings.refresh_cookie_samesite,
max_age=settings.refresh_token_expire_days * 24 * 60 * 60,
path="/api/v1/auth",
)
def _clear_refresh_cookie(response: Response) -> None:
def _clear_refresh_cookie(request: Request, response: Response) -> None:
response.delete_cookie(
key=settings.refresh_cookie_name,
path="/api/v1/auth",
httponly=True,
secure=settings.refresh_cookie_secure,
secure=_refresh_cookie_secure(request),
samesite=settings.refresh_cookie_samesite,
)
@@ -71,7 +84,7 @@ def register(
user_agent=request.headers.get("user-agent"),
ip_address=_client_ip(request),
)
_set_refresh_cookie(response, result.refresh_token)
_set_refresh_cookie(request, response, result.refresh_token)
return _to_auth_response(result)
@@ -88,7 +101,7 @@ def login(
user_agent=request.headers.get("user-agent"),
ip_address=_client_ip(request),
)
_set_refresh_cookie(response, result.refresh_token)
_set_refresh_cookie(request, response, result.refresh_token)
return _to_auth_response(result)
@@ -104,7 +117,7 @@ def refresh(
user_agent=request.headers.get("user-agent"),
ip_address=_client_ip(request),
)
_set_refresh_cookie(response, result.refresh_token)
_set_refresh_cookie(request, response, result.refresh_token)
return _to_auth_response(result)
@@ -119,7 +132,7 @@ def logout(
request.cookies.get(settings.refresh_cookie_name),
user_id=None,
)
_clear_refresh_cookie(response)
_clear_refresh_cookie(request, response)
return MessageResponse(message="Logged out")
+30
View File
@@ -0,0 +1,30 @@
## Work Log - graphify 构建 api/app 后端知识图谱(2026-05-12
- 背景:
-`./api/app` 执行 `$graphify`,目标是生成后端结构图谱,辅助后续代码导航与跨模块关系追踪。
- 仓库根目录检测结果超过 graphify 建议阈值,因此改为对子目录 `api/app` 单独建图。
- 语料与执行结果:
- `api/app` 检测为纯代码语料:`110` 个代码文件,约 `60,168` 词。
- 按 graphify 规则跳过 semantic extraction,仅执行 AST 抽取、聚类、报告与 HTML 可视化。
- 产物位于仓库根目录 `graphify-out/`
- `graph.html`
- `GRAPH_REPORT.md`
- `graph.json`
- `cost.json`
- `manifest.json`
- 关键指标:
- 图规模:`1174` nodes / `3445` edges / `35` communities。
- Token benchmark
- 语料约 `80,224` naive tokens
- 平均查询成本约 `12,893` tokens
-`6.2x` token reduction per query
- 关注点:
- 主要桥接节点包括 `utcnow()``publish_topic()``Base``UserPublic``normalize_virtual_path()`
- 低内聚社区主要集中在 `Elevation Workflow``Lightning Analysis`,适合后续做依赖与职责拆分审视。
- 风险与影响:
- 本次未改业务代码,仅新增图谱输出与当天记忆文件。
- `graphify-out/``api/app/graphify-out/cache/ast/` 为新生成工件,提交前应按需要决定是否纳入版本管理。
+21
View File
@@ -128,3 +128,24 @@
- 风险与关注点:
- 当前别名映射基于已知历史菜单路径补齐;若库里还存在其他非常规旧 path,仍需按实际反馈继续补别名表。
## Work Log - 生产入口 `/fl/login` 404 排查与 host Nginx 修复(2026-05-16
- 背景:
- 线上 `https://www.quizck.cn/fl/login` 一度返回 404,但仓库内 `web` 容器与本地代理均已包含 `/login` 页面。
- 进一步比对发现,问题出在宿主机 Nginx 的 `/fl` 精确匹配:`location = /fl { return 301 /fl/; }` 会把入口导向 `/fl/`,而 Next 在 `/fl/` 上又会归一回 `/fl`,形成不必要的重定向回环/错路由链。
- 本次修复:
- `/etc/nginx/conf.d/quiz.conf`
-`location = /fl` 的重定向目标改为 `/fl/login`
- 保留 `location ^~ /fl/` 继续反代到 `127.0.0.1:3000`
- 执行 `nginx -t && nginx -s reload` 让配置立即生效。
- 验证:
- `curl -I https://www.quizck.cn/fl/login` 返回 `200 OK`
- `curl -IL https://www.quizck.cn/fl` 返回 `301 -> /fl/login -> 200`
- `curl -IL https://www.quizck.cn/fl/` 返回 `308 -> /fl -> /fl/login -> 200`
- 风险与关注点:
- `/fl/` 仍会多一次跳转,但不再出现 404。
- 后续若统一外部入口,优先直接使用 `/fl/login`,避免再依赖 `/fl` 的归一逻辑。
+3 -15
View File
@@ -39,18 +39,6 @@ function stripBasePath(pathname: string): string {
return pathname;
}
function withBasePath(pathname: string): string {
if (!APP_BASE_PATH) {
return pathname;
}
if (pathname === "/") {
return APP_BASE_PATH;
}
return `${APP_BASE_PATH}${pathname}`;
}
function isBypassedPath(pathname: string): boolean {
if (pathname === "/" || pathname === "/login" || pathname === "/login/") {
return true;
@@ -75,18 +63,18 @@ export function middleware(request: NextRequest) {
// Keep backward compatibility for existing /admin links and legacy menu aliases.
if (pathname.startsWith("/admin/")) {
const url = request.nextUrl.clone();
url.pathname = withBasePath(canonicalPath);
url.pathname = canonicalPath;
return NextResponse.redirect(url);
}
if (canonicalPath !== pathname) {
const url = request.nextUrl.clone();
url.pathname = withBasePath(canonicalPath);
url.pathname = canonicalPath;
return NextResponse.redirect(url);
}
// New public URLs without /admin are internally rewritten to existing routes.
const url = request.nextUrl.clone();
url.pathname = withBasePath(`/admin${canonicalPath}`);
url.pathname = `/admin${canonicalPath}`;
return NextResponse.rewrite(url);
}