docs(readme): add doc
This commit is contained in:
@@ -35,6 +35,7 @@ import { encrypt, getQueryVariable, validatePhoneNumber } from "./util";
|
||||
const HeaderIcon = DigitalIcon;
|
||||
const headerTitle = "酷哇数字化平台";
|
||||
const fixedTenant = "coowa";
|
||||
const ssoStateStorageKey = (appId: string) => `sso_state:${appId}`;
|
||||
|
||||
export default function LoginPage() {
|
||||
const colorScheme = useComputedColorScheme();
|
||||
@@ -59,20 +60,24 @@ export default function LoginPage() {
|
||||
// SSO 跳转参数
|
||||
const isClient = typeof window !== "undefined";
|
||||
const appId = isClient ? (getQueryVariable("app_id") as string) || "" : "";
|
||||
const appUrl = isClient
|
||||
? decodeURIComponent((getQueryVariable("app_url") as string) || "")
|
||||
: "";
|
||||
const appUrl = isClient ? (getQueryVariable("app_url") as string) || "" : "";
|
||||
const state = isClient ? (getQueryVariable("state") as string) || "" : "";
|
||||
|
||||
// 缺少 app_id 或 app_url 时不允许登录(sso-portal 自身不需要登录)
|
||||
const missingSsoParams = !appId || !appUrl;
|
||||
|
||||
// 持久化 SSO 参数:飞书 OAuth 跳转后会丢失 URL 参数,存 localStorage
|
||||
// 持久化 SSO 参数:飞书 OAuth 跳转后会丢失 URL 参数。
|
||||
useEffect(() => {
|
||||
if (appId && appUrl) {
|
||||
localStorage.setItem(appId, appUrl); // app_id -> app_url
|
||||
localStorage.setItem("sso_app_id", appId); // 记住当前 app_id
|
||||
if (state) {
|
||||
sessionStorage.setItem(ssoStateStorageKey(appId), state);
|
||||
} else {
|
||||
sessionStorage.removeItem(ssoStateStorageKey(appId));
|
||||
}
|
||||
}
|
||||
}, [appId, appUrl]);
|
||||
}, [appId, appUrl, state]);
|
||||
|
||||
// 获取租户简称列表(与 uirefbase 一致)
|
||||
useEffect(() => {
|
||||
@@ -118,17 +123,33 @@ export default function LoginPage() {
|
||||
const storedAppId = appId || localStorage.getItem("sso_app_id") || "";
|
||||
const targetUrl =
|
||||
appUrl || (storedAppId ? localStorage.getItem(storedAppId) || "" : "");
|
||||
const callbackState =
|
||||
(appId && appUrl ? state : "") ||
|
||||
(storedAppId
|
||||
? sessionStorage.getItem(ssoStateStorageKey(storedAppId)) || ""
|
||||
: "");
|
||||
|
||||
if (res?.code && targetUrl) {
|
||||
const separator = targetUrl.includes("?") ? "&" : "?";
|
||||
window.location.href = `${targetUrl}${separator}sso_code=${res.code}`;
|
||||
try {
|
||||
const callbackUrl = new URL(targetUrl);
|
||||
callbackUrl.searchParams.set("sso_code", res.code);
|
||||
if (callbackState) {
|
||||
callbackUrl.searchParams.set("state", callbackState);
|
||||
}
|
||||
if (storedAppId) {
|
||||
sessionStorage.removeItem(ssoStateStorageKey(storedAppId));
|
||||
}
|
||||
window.location.href = callbackUrl.toString();
|
||||
} catch {
|
||||
setError("外部应用回调地址(app_url)格式无效,无法完成 SSO 跳转");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 无外部应用地址 — sso-portal 不提供本地登录
|
||||
setError("缺少外部应用回调地址(app_url),无法完成 SSO 跳转");
|
||||
},
|
||||
[appId, appUrl],
|
||||
[appId, appUrl, state],
|
||||
);
|
||||
|
||||
// ============ 统一调用 /api/login ============
|
||||
|
||||
Reference in New Issue
Block a user