1
0
forked from baron/baron-sso

front류 개발모드에서는 세션 갱신 끄기

This commit is contained in:
2026-05-20 11:48:31 +09:00
parent 0031784c07
commit 0155ee4ee7
17 changed files with 287 additions and 23 deletions

View File

@@ -2,6 +2,7 @@ import { useState } from "react";
import { t } from "../../lib/i18n";
const LOCALE_STORAGE_KEY = "locale";
const LOCALE_CHANGED_EVENT = "baron_locale_changed";
const SUPPORTED_LOCALES = ["ko", "en"] as const;
type Locale = (typeof SUPPORTED_LOCALES)[number];
@@ -34,6 +35,10 @@ function LanguageSelector() {
}
window.localStorage.setItem(LOCALE_STORAGE_KEY, next);
setLocale(next);
if (import.meta.env.MODE === "development") {
window.dispatchEvent(new Event(LOCALE_CHANGED_EVENT));
return;
}
window.location.reload();
};

View File

@@ -32,6 +32,8 @@ import {
import LanguageSelector from "../common/LanguageSelector";
import { Toaster } from "../ui/toaster";
const LOCALE_CHANGED_EVENT = "baron_locale_changed";
const navItems = [
{
labelKey: "ui.dev.nav.clients",
@@ -97,10 +99,12 @@ function AppLayout() {
const isRenewInFlightRef = useRef(false);
const lastRenewAttemptAtRef = useRef(0);
const lastVisitedRouteRef = useRef<string | null>(null);
const isDevelopmentRuntime = import.meta.env.MODE === "development";
const [theme, setTheme] = useState<"light" | "dark">(readShellTheme);
const [isProfileMenuOpen, setIsProfileMenuOpen] = useState(false);
const [isSessionExpiryEnabled, setIsSessionExpiryEnabled] = useState(
readShellSessionExpiryEnabled,
const [, setDevelopmentRenderRevision] = useState(0);
const [isSessionExpiryEnabled, setIsSessionExpiryEnabled] = useState(() =>
readShellSessionExpiryEnabled(!isDevelopmentRuntime),
);
const hasAccessToken = Boolean(auth.user?.access_token);
const { data: profile } = useQuery({
@@ -120,6 +124,22 @@ function AppLayout() {
applyShellTheme(theme);
}, [theme]);
useEffect(() => {
if (!isDevelopmentRuntime) {
return;
}
const rerenderDevelopmentShell = () => {
setDevelopmentRenderRevision((value) => value + 1);
};
window.addEventListener(LOCALE_CHANGED_EVENT, rerenderDevelopmentShell);
return () => {
window.removeEventListener(LOCALE_CHANGED_EVENT, rerenderDevelopmentShell);
};
}, [isDevelopmentRuntime]);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (
@@ -185,6 +205,10 @@ function AppLayout() {
]);
useEffect(() => {
if (isDevelopmentRuntime) {
return;
}
const maybeKeepSessionAlive = async () => {
const now = Date.now();
if (
@@ -227,6 +251,7 @@ function AppLayout() {
auth.isAuthenticated,
auth.isLoading,
auth.user?.expires_at,
isDevelopmentRuntime,
isSessionExpiryEnabled,
]);

View File

@@ -1,10 +1,11 @@
import { useAuth } from "react-oidc-context";
import { Navigate, Outlet, useLocation } from "react-router-dom";
import { Navigate, Outlet, useLocation, useNavigate } from "react-router-dom";
import { t } from "../../lib/i18n";
export default function AuthGuard() {
const auth = useAuth();
const location = useLocation();
const navigate = useNavigate();
const searchParams = new URLSearchParams(location.search);
const shareToken = searchParams.get("token");
const isPlaywrightBypass =
@@ -57,7 +58,7 @@ export default function AuthGuard() {
className="inline-flex items-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:opacity-90"
onClick={() => {
auth.removeUser();
window.location.href = "/login";
navigate("/login");
}}
>
{t("ui.common.back_to_login", "로그인으로 돌아가기")}

View File

@@ -1,5 +1,8 @@
import axios from "axios";
import { shouldStartLoginRedirect } from "../../../common/core/auth";
import {
shouldSuppressDevelopmentSessionRedirect,
} from "../../../common/core/session";
import { userManager } from "./auth";
let isRedirectingToLogin = false;
@@ -42,8 +45,22 @@ apiClient.interceptors.response.use(
message.includes("invalid session") ||
message.includes("token is not active")));
if (!shouldRedirectToLogin) {
return Promise.reject(error);
}
if (
shouldSuppressDevelopmentSessionRedirect({
appMode: import.meta.env.MODE,
})
) {
console.warn(
"[apiClient] Auth failure detected, but development session redirects are disabled.",
);
return Promise.reject(error);
}
if (
shouldRedirectToLogin &&
shouldStartLoginRedirect({
pathname: window.location.pathname,
isRedirecting: isRedirectingToLogin,