fix: 전 시스템 Chrome 무한 로그인 루프 해결 및 role 대소문자 통일
- gateway: 로그인 페이지 자동 리다이렉트 시 SSO 쿠키 재설정 + Cache-Control no-store - tkreport(system2): SW 해제, 401 핸들러 리다이렉트 제거, 루프 방지, localStorage 백업 - TKQC 모바일(system3): mCheckAuth를 authManager 위임으로 변경, 루프 방지 - TKQC 공통(system3): api.js 로그인 URL 캐시 버스팅, auth-manager localStorage 백업 - tkuser: SW 해제, 401 핸들러 수정, 루프 방지, localStorage 백업, requireAdmin role 소문자 통일 - system1: 작업보고서 admin role 대소문자 무시, refresh 토큰에 role 필드 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -189,7 +189,7 @@
|
||||
<script src="/static/js/core/auth-manager.js?v=20260308"></script>
|
||||
<script src="/static/js/core/permissions.js?v=20260308"></script>
|
||||
<script src="/static/js/utils/issue-helpers.js?v=20260308"></script>
|
||||
<script src="/static/js/m/m-common.js?v=20260308"></script>
|
||||
<script src="/static/js/m/m-common.js?v=20260309"></script>
|
||||
<script src="/static/js/m/m-dashboard.js?v=20260308"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
<script src="/static/js/core/auth-manager.js?v=20260308"></script>
|
||||
<script src="/static/js/core/permissions.js?v=20260308"></script>
|
||||
<script src="/static/js/utils/issue-helpers.js?v=20260308"></script>
|
||||
<script src="/static/js/m/m-common.js?v=20260308"></script>
|
||||
<script src="/static/js/m/m-common.js?v=20260309"></script>
|
||||
<script src="/static/js/m/m-inbox.js?v=20260308"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
<script src="/static/js/core/auth-manager.js?v=20260308"></script>
|
||||
<script src="/static/js/core/permissions.js?v=20260308"></script>
|
||||
<script src="/static/js/utils/issue-helpers.js?v=20260308"></script>
|
||||
<script src="/static/js/m/m-common.js?v=20260308"></script>
|
||||
<script src="/static/js/m/m-common.js?v=20260309"></script>
|
||||
<script src="/static/js/m/m-management.js?v=20260308"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -11,13 +11,14 @@ function _cookieRemove(name) {
|
||||
document.cookie = cookie;
|
||||
}
|
||||
|
||||
// 중앙 로그인 URL
|
||||
// 중앙 로그인 URL (캐시 버스팅 포함)
|
||||
function _getLoginUrl() {
|
||||
const hostname = window.location.hostname;
|
||||
const t = Date.now();
|
||||
if (hostname.includes('technicalkorea.net')) {
|
||||
return window.location.protocol + '//tkfb.technicalkorea.net/login?redirect=' + encodeURIComponent(window.location.href);
|
||||
return window.location.protocol + '//tkfb.technicalkorea.net/login?redirect=' + encodeURIComponent(window.location.href) + '&_t=' + t;
|
||||
}
|
||||
return window.location.protocol + '//' + hostname + ':30000/login?redirect=' + encodeURIComponent(window.location.href);
|
||||
return window.location.protocol + '//' + hostname + ':30000/login?redirect=' + encodeURIComponent(window.location.href) + '&_t=' + t;
|
||||
}
|
||||
|
||||
// API 기본 설정 (통합 환경 지원)
|
||||
|
||||
@@ -154,7 +154,9 @@ class AuthManager {
|
||||
this.isAuthenticated = true;
|
||||
this.lastAuthCheck = Date.now();
|
||||
|
||||
// localStorage 업데이트
|
||||
// localStorage 업데이트 (쿠키 소실 대비 백업)
|
||||
const token = this._getToken();
|
||||
if (token) localStorage.setItem('sso_token', token);
|
||||
localStorage.setItem('sso_user', JSON.stringify(user));
|
||||
|
||||
this.notifyListeners('auth-success', user);
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
})();
|
||||
|
||||
/* ===== KST Date Utilities ===== */
|
||||
// DB에 KST로 저장된 naive datetime을 그대로 표시 (이중 변환 방지)
|
||||
function getKSTDate(date) {
|
||||
var d = new Date(date);
|
||||
return new Date(d.getTime() + 9 * 60 * 60 * 1000);
|
||||
return new Date(date);
|
||||
}
|
||||
function formatKSTDate(date) {
|
||||
return new Date(date).toLocaleDateString('ko-KR', { timeZone: 'Asia/Seoul' });
|
||||
@@ -27,13 +27,12 @@ function formatKSTDateTime(date) {
|
||||
return new Date(date).toLocaleString('ko-KR', { timeZone: 'Asia/Seoul', year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });
|
||||
}
|
||||
function getKSTToday() {
|
||||
var now = new Date();
|
||||
var kst = getKSTDate(now);
|
||||
var kst = new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Seoul' }));
|
||||
return new Date(kst.getFullYear(), kst.getMonth(), kst.getDate());
|
||||
}
|
||||
function getTimeAgo(date) {
|
||||
var now = getKSTDate(new Date());
|
||||
var d = getKSTDate(date);
|
||||
var now = new Date();
|
||||
var d = new Date(date);
|
||||
var diff = now - d;
|
||||
var mins = Math.floor(diff / 60000);
|
||||
var hours = Math.floor(diff / 3600000);
|
||||
@@ -147,20 +146,45 @@ function closePhotoModal() {
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== Auth Helper ===== */
|
||||
/* ===== Auth Helper (authManager 위임 + 루프 방지) ===== */
|
||||
var _mRedirectKey = '_sso_redirect_ts';
|
||||
var _mRedirectCooldown = 5000; // 5초 내 재리다이렉트 방지
|
||||
|
||||
function _mSafeRedirectToLogin() {
|
||||
var last = parseInt(sessionStorage.getItem(_mRedirectKey) || '0', 10);
|
||||
if (Date.now() - last < _mRedirectCooldown) {
|
||||
console.warn('[TKQC-M] 리다이렉트 루프 감지 — 로그인 페이지로 이동하지 않음');
|
||||
return;
|
||||
}
|
||||
sessionStorage.setItem(_mRedirectKey, String(Date.now()));
|
||||
window.location.href = _getLoginUrl();
|
||||
}
|
||||
|
||||
async function mCheckAuth() {
|
||||
// authManager가 있으면 위임 (SW 정리 + 캐시 관리 포함)
|
||||
if (window.authManager && typeof window.authManager.checkAuth === 'function') {
|
||||
var user = await window.authManager.checkAuth();
|
||||
if (user) {
|
||||
sessionStorage.removeItem(_mRedirectKey);
|
||||
return user;
|
||||
}
|
||||
_mSafeRedirectToLogin();
|
||||
return null;
|
||||
}
|
||||
// 폴백: authManager 없는 경우
|
||||
var token = TokenManager.getToken();
|
||||
if (!token) {
|
||||
window.location.href = _getLoginUrl();
|
||||
_mSafeRedirectToLogin();
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
var user = await AuthAPI.getCurrentUser();
|
||||
sessionStorage.removeItem(_mRedirectKey);
|
||||
return user;
|
||||
} catch (e) {
|
||||
TokenManager.removeToken();
|
||||
TokenManager.removeUser();
|
||||
window.location.href = _getLoginUrl();
|
||||
_mSafeRedirectToLogin();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user