feat: HttpOnly Cookie 登入狀態初始化

This commit is contained in:
skytek_xinliang
2026-08-31 09:26:47 +08:00
parent db089ce267
commit 28cda7be1c
5 changed files with 60 additions and 7 deletions
+35
View File
@@ -317,6 +317,8 @@ function createDefaultRadarData() {
export const useAppStore = defineStore("app", () => {
const isLoggedIn = ref(false);
const isAuthInitialized = ref(false);
let authInitializationPromise: Promise<boolean> | null = null;
/** 僅供前端顯示或其他使用者資料用途;course/group 不再傳送此值。 */
const userID = ref("");
const userProfile = ref<UserProfile>(createEmptyUserProfile());
@@ -368,6 +370,37 @@ export const useAppStore = defineStore("app", () => {
};
}
/** 以 HttpOnly Cookie 還原頁面重新整理後的登入狀態。 */
async function initializeAuthentication(): Promise<boolean> {
if (isAuthInitialized.value) {
return isLoggedIn.value;
}
if (authInitializationPromise) {
return authInitializationPromise;
}
authInitializationPromise = (async () => {
try {
if (!USE_MOCK) {
const profile = await apiGetProfile();
isLoggedIn.value = true;
userProfile.value = applyProfileToStore(profile);
}
return isLoggedIn.value;
} catch {
// 未登入時 profile API 會回 401,維持訪客狀態即可。
clearAuthentication();
return false;
} finally {
isAuthInitialized.value = true;
}
})();
return authInitializationPromise;
}
/** 使用手機門號與密碼登入,成功後只保存非敏感的回應資料。 */
async function login(phone: string, password: string): Promise<AuthResponse> {
if (!password) {
@@ -666,6 +699,7 @@ export const useAppStore = defineStore("app", () => {
return {
isLoggedIn,
isAuthInitialized,
userID,
userProfile,
selfAssessment,
@@ -679,6 +713,7 @@ export const useAppStore = defineStore("app", () => {
progressPercent,
login,
register,
initializeAuthentication,
logout,
clearAuthentication,
updateProfile,