fix: harden org switch token validation and exit org page

Validate current_org_id from switch token before accepting it, align auth/sudo tokens, and force full navigation to home after switch to avoid staying on org-select state.

Made-with: Cursor
This commit is contained in:
2026-04-27 23:59:56 +08:00
parent da9c365fc0
commit 713af27749
2 changed files with 36 additions and 8 deletions
+1 -5
View File
@@ -43,11 +43,7 @@ export default defineComponent({
if (!switched) {
return;
}
const currentAuthToken = window.localStorage.getItem(HtyAuthToken);
if (currentAuthToken) {
window.localStorage.setItem(HtySudoToken, currentAuthToken);
}
await router.replace("/");
window.location.assign("/");
};
return { orgs, onSelect };
+35 -3
View File
@@ -1,6 +1,6 @@
import { reactive } from "vue";
import request from "~/utils/request";
import { CurrentOrgId, HtyAuthToken } from "~/utils";
import { CurrentOrgId, HtyAuthToken, HtySudoToken } from "~/utils";
import type { Organization } from "~/types";
import { showFailToast } from "vant";
@@ -16,6 +16,28 @@ const store = reactive<OrgState>({
homepageMd: "",
});
const parseCurrentOrgIdFromToken = (token: string): string | undefined => {
try {
const tokenParts = token.split(".");
if (tokenParts.length < 2) return undefined;
const payloadRaw = tokenParts[1].replace(/-/g, "+").replace(/_/g, "/");
const payloadRawWithPadding = payloadRaw.padEnd(
Math.ceil(payloadRaw.length / 4) * 4,
"="
);
const payloadJson = decodeURIComponent(
atob(payloadRawWithPadding)
.split("")
.map((char) => `%${(`00${char.charCodeAt(0).toString(16)}`).slice(-2)}`)
.join("")
);
const payload = JSON.parse(payloadJson);
return payload.current_org_id || undefined;
} catch (_error) {
return undefined;
}
};
export default function useOrg() {
const loadMyOrgs = async () => {
const { r, d, e } = await request({
@@ -41,9 +63,19 @@ export default function useOrg() {
showFailToast(e);
return false;
}
if (typeof d !== "string") {
showFailToast("机构切换失败:返回 token 非法");
return false;
}
const tokenOrgId = parseCurrentOrgIdFromToken(d);
if (!tokenOrgId) {
showFailToast("机构切换失败:token 缺少机构上下文");
return false;
}
window.localStorage.setItem(HtyAuthToken, d);
window.localStorage.setItem(CurrentOrgId, orgId);
store.currentOrgId = orgId;
window.localStorage.setItem(HtySudoToken, d);
window.localStorage.setItem(CurrentOrgId, tokenOrgId);
store.currentOrgId = tokenOrgId;
return true;
};