/** 客户端全局鉴权与安全回跳;旧平台凭证入口先脱敏,再由专页向后端确认身份。 */ 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("/"); });