Files
console-dev/app/middleware/auth.global.js
T

58 lines
2.2 KiB
JavaScript

/** 客户端全局鉴权与安全回跳;旧平台凭证入口先脱敏,再由专页向后端确认身份。 */
import { defineNuxtRouteMiddleware, navigateTo } from "#app";
import { useAuth } from "~/lib/auth.js";
import { r as safeRedirect } from "~/lib/auth-redirect.js";
import { isAuthPage, isPublicRoute } from "~/utils/access.js";
export default defineNuxtRouteMiddleware((to) => {
const auth = useAuth();
// queryParam 是旧平台携带的敏感 JWT:只进入内存待验证状态,立即从地址和路由中移除。
if (to.path === "/home.htm") {
if (Object.hasOwn(to.query, "queryParam") || !auth.legacyLoginPending) {
auth.prepareLegacyLogin(to.query.queryParam);
}
if (Object.hasOwn(to.query, "queryParam")) {
const url = new URL(window.location.href);
url.searchParams.delete("queryParam");
window.history.replaceState(
window.history.state,
"",
url.pathname + url.search + url.hash,
);
const query = { ...to.query };
delete query.queryParam;
// Canonicalize the router location too; mutating query alone leaves fullPath with the credential.
return navigateTo(
{ path: "/home.htm", query, hash: to.hash },
{ replace: true },
);
}
return;
}
// 非公开页保留安全的站内目的地,但绝不把旧平台凭证夹带进登录 redirect。
if (!auth.isLoggedIn && !isPublicRoute(to)) {
const query = { ...to.query };
delete query.queryParam;
const params = new URLSearchParams();
for (const [key, value] of Object.entries(query)) {
for (const item of Array.isArray(value) ? value : [value])
if (item != null) params.append(key, item);
}
const redirect = safeRedirect(
to.path + (params.size ? "?" + params : "") + to.hash,
);
return navigateTo({
path: "/login",
query: redirect === "/" ? {} : { redirect },
});
}
// 已登录用户通常无需返回登录页;OAuth 回调、微信绑定和官网仍允许访问。
if (
auth.isLoggedIn &&
isAuthPage(to.path) &&
!["/oauth/callback", "/official-site"].includes(to.path) &&
!(to.path === "/oauth/bind" && to.query.provider === "wechat")
)
return navigateTo("/");
});