Web 应用的“按需登录”与“意图回跳”
Contents
第一步:记录意图
在组件中,我们不再直接跳转,而是先过一遍“安检”。
// KbCard.vue
const openChat = () => {
const targetUrl = `/chat?kb=${props.id}`;
// 调用通用的检查登录方法,并告诉它:登录完我想去 targetUrl
if (userStore.checkLogin({ message: "请先登录", redirectUrl: targetUrl })) {
router.push(targetUrl);
}
};第二步:持久化存储
因为登录通常涉及跨页面跳转(如跳转到 SSO 统一认证平台),我们需要把这个“意图”存入浏览器的 sessionStorage。
// userStore.js
const initUser = (forceRedirect, customRedirect) => {
if (forceRedirect) {
// 将相对路径补全为绝对路径,确跳转绝对准确
const redirectUrl = customRedirect || window.location.href;
sessionStorage.setItem("redirectUrl", redirectUrl); // 存入“小本本”
// 跳转 SSO 登录页
window.location.href = `SSO_URL...`;
}
};第三步:认证回调
用户登录成功,SSO 会把用户送回我们的网站,并带上 Token。此时页面会重新加载。
第四步:意图还原
在路由跳转前,我们翻开“小本本”,看看有没有还没完成的愿望。
// router/index.js
router.beforeEach((to, from, next) => {
const token = to.query.AccessToken;
if (token) {
// 1. 翻看小本本
const redirectUrl = sessionStorage.getItem("redirectUrl");
if (redirectUrl) {
sessionStorage.removeItem("redirectUrl"); // 读完就撕掉,防止重复跳转
const url = new URL(redirectUrl);
const targetPath = url.pathname;
const query = Object.fromEntries(new URLSearchParams(url.search));
// 2. 净化 URL,剔除认证相关的参数
delete query.AccessToken;
// 3. 无感回跳到目标页面
next({ path: targetPath, query, replace: true });
return;
}
}
next();
});