feat: 优化web
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
'use client';
|
||||
|
||||
import { create } from 'zustand';
|
||||
import { loginWithPassword, logoutRequest, type TokenPair } from '@/lib/api/auth';
|
||||
import { registerTokenBridge } from '@/lib/api/client';
|
||||
import { broadcastLogout } from '@/lib/sync/logout-broadcast';
|
||||
|
||||
const STORAGE_KEY = 'smart_auth_tokens';
|
||||
|
||||
function loadFromSession(): Pick<AuthState, 'accessToken' | 'refreshToken'> {
|
||||
if (typeof window === 'undefined') {
|
||||
return { accessToken: null, refreshToken: null };
|
||||
}
|
||||
try {
|
||||
const raw = sessionStorage.getItem(STORAGE_KEY);
|
||||
if (!raw) {
|
||||
return { accessToken: null, refreshToken: null };
|
||||
}
|
||||
const p = JSON.parse(raw) as { accessToken?: string; refreshToken?: string };
|
||||
return { accessToken: p.accessToken ?? null, refreshToken: p.refreshToken ?? null };
|
||||
} catch {
|
||||
return { accessToken: null, refreshToken: null };
|
||||
}
|
||||
}
|
||||
|
||||
type AuthState = {
|
||||
accessToken: string | null;
|
||||
refreshToken: string | null;
|
||||
setTokens: (access: string | null, refresh: string | null) => void;
|
||||
login: (userName: string, password: string, tenantId?: string) => Promise<void>;
|
||||
logout: () => Promise<void>;
|
||||
};
|
||||
|
||||
export const useAuthStore = create<AuthState>((set) => {
|
||||
const initial = loadFromSession();
|
||||
|
||||
const persist = (accessToken: string | null, refreshToken: string | null) => {
|
||||
set({ accessToken, refreshToken });
|
||||
if (typeof window !== 'undefined') {
|
||||
if (accessToken || refreshToken) {
|
||||
sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ accessToken, refreshToken }));
|
||||
} else {
|
||||
sessionStorage.removeItem(STORAGE_KEY);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
accessToken: initial.accessToken,
|
||||
refreshToken: initial.refreshToken,
|
||||
|
||||
setTokens: (access, refresh) => {
|
||||
persist(access, refresh);
|
||||
},
|
||||
|
||||
login: async (userName, password, tenantId) => {
|
||||
const pair: TokenPair = await loginWithPassword({ userName, password, tenantId });
|
||||
persist(pair.accessToken, pair.refreshToken);
|
||||
},
|
||||
|
||||
logout: async () => {
|
||||
try {
|
||||
await logoutRequest();
|
||||
} finally {
|
||||
persist(null, null);
|
||||
broadcastLogout();
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
registerTokenBridge(
|
||||
() => ({
|
||||
accessToken: useAuthStore.getState().accessToken,
|
||||
refreshToken: useAuthStore.getState().refreshToken,
|
||||
}),
|
||||
(access, refresh) => useAuthStore.getState().setTokens(access, refresh)
|
||||
);
|
||||
Reference in New Issue
Block a user