자동 로그아웃 설정 변경
eapim-admin CI / build (push) Has been cancelled

This commit is contained in:
eastargh
2026-08-26 14:59:29 +09:00
parent e69e1a1031
commit 497b72c52a
9 changed files with 53 additions and 13 deletions
+1 -1
View File
@@ -175,6 +175,6 @@
</jsp-config> </jsp-config>
<session-config> <session-config>
<session-timeout>10</session-timeout> <session-timeout>30</session-timeout>
</session-config> </session-config>
</web-app> </web-app>
+1 -1
View File
@@ -145,6 +145,6 @@
</jsp-config> </jsp-config>
<session-config> <session-config>
<session-timeout>10</session-timeout> <session-timeout>30</session-timeout>
</session-config> </session-config>
</web-app> </web-app>
+6 -2
View File
@@ -31,8 +31,12 @@
<script language="javascript" src="<c:url value="/js/custom.js"/>"></script> <script language="javascript" src="<c:url value="/js/custom.js"/>"></script>
<script language="javascript" src="<c:url value="/js/common-${locale}.js"/>"></script> <script language="javascript" src="<c:url value="/js/common-${locale}.js"/>"></script>
<script type="text/javascript"> <script type="text/javascript">
/* 자동 로그아웃: iframe 내 활동을 sessionStorage에 기록 (main.jsp 타이머와 공유) */ /* 자동 로그아웃: 서버로 실제 요청이 발생한 경우에만 활동으로 기록 (main.jsp 타이머와 sessionStorage 공유) */
(function() { var m = function() { sessionStorage.setItem('lastActivity', String(Date.now())); }; ['mousemove','keydown','click','touchstart'].forEach(function(e){ document.addEventListener(e, m, true); }); })(); (function() {
var mark = function() { sessionStorage.setItem('lastActivity', String(Date.now())); };
mark(); // 화면(프레임) 로드 자체가 서버 요청이므로 활동으로 기록
$(document).ajaxSend(mark); // 이후 이 프레임에서 발생하는 모든 AJAX 요청을 활동으로 기록
})();
</script> </script>
<script language="javascript" src="<c:url value="/js/jquery.inputmask.bundle.min.js"/>"></script> <script language="javascript" src="<c:url value="/js/jquery.inputmask.bundle.min.js"/>"></script>
<script language="javascript" src="<c:url value="/js/jquery.searchabledropdown-1.0.8.min.js"/>"></script> <script language="javascript" src="<c:url value="/js/jquery.searchabledropdown-1.0.8.min.js"/>"></script>
@@ -305,11 +305,13 @@
}); });
$("input[name=changePassword]").keydown(function(event){ $("input[name=changePassword]").keydown(function(event){
if ( event.which == 13 ) { if ( event.which == 13 ) {
event.preventDefault();
submitChangePassword(); submitChangePassword();
} }
}); });
$("input[name=confirmPassword]").keydown(function(event){ $("input[name=confirmPassword]").keydown(function(event){
if ( event.which == 13 ) { if ( event.which == 13 ) {
event.preventDefault();
submitChangePassword(); submitChangePassword();
} }
}); });
+2 -4
View File
@@ -166,10 +166,8 @@
location.href = '<%=request.getContextPath()%>/rms/logout.do'; location.href = '<%=request.getContextPath()%>/rms/logout.do';
} }
/* 상위 프레임(main.jsp) 활동 감지 */ /* 상위 프레임(main.jsp)에서 발생하는 AJAX 요청만 활동으로 기록 (마우스 이동/클릭만으로는 갱신되지 않음) */
['mousemove', 'keydown', 'click', 'touchstart'].forEach(function (e) { $(document).ajaxSend(markActivity);
document.addEventListener(e, markActivity, true);
});
/* 주기적 유휴 시간 체크 */ /* 주기적 유휴 시간 체크 */
setInterval(function () { setInterval(function () {
+32 -3
View File
@@ -555,7 +555,35 @@
<% session.setAttribute("dualLogin", "N"); %> <% session.setAttribute("dualLogin", "N"); %>
} }
}); });
// 세션(자동로그아웃) 타임아웃 카운트다운 - main.jsp의 유휴시간 판단과 동일한 sessionStorage 값을 공유한다.
(function () {
var IDLE_MS = ${autoLogoutTimeout} * 60 * 1000;
function getLastActivity() {
var t = sessionStorage.getItem('lastActivity');
return t ? parseInt(t, 10) : Date.now();
}
function formatRemain(ms) {
if (ms < 0) ms = 0;
var totalSec = Math.floor(ms / 1000);
var mm = Math.floor(totalSec / 60);
var ss = totalSec % 60;
return (mm < 10 ? '0' + mm : mm) + ':' + (ss < 10 ? '0' + ss : ss);
}
function updateSessionTimeoutTimer() {
var remain = IDLE_MS - (Date.now() - getLastActivity());
$('#sessionTimeoutTimer').text('세션 만료까지 ' + formatRemain(remain));
}
$(function () {
updateSessionTimeoutTimer();
setInterval(updateSessionTimeoutTimer, 1000);
});
})();
</script> </script>
</head> </head>
@@ -568,11 +596,12 @@
<ul> <ul>
<li style="width:240px;"> <li style="width:240px;">
<a style="width:240px; cursor: default" <a style="width:240px; cursor: default"
href="#"><span><%=SessionManager.getUserName(request) %>(<%=SessionManager.getUserId(request) %>-<%=System.getProperty("inst.Name") %>)</span> href="#"><span><%=SessionManager.getUserName(request) %>(<%=SessionManager.getUserId(request) %></span>
<span onClick="javascript:openColorPopup();"><%=localeMessage.getString("screen.customer") %></span> <span onClick="javascript:openColorPopup();"><%=localeMessage.getString("screen.customer") %></span>
<% if (!"".equals(LastLoginYms.trim())) { %> <% if (!"".equals(LastLoginYms.trim())) { %>
<span style="display:block;font-size:10px;"><%=localeMessage.getString("screen.lastLogin") %> : <%=LastLoginYms%> [ <%=LastLoginIp%> ]</span> <span style="display:block;font-size:10px;"><%=localeMessage.getString("screen.lastLogin") %> : <%=LastLoginYms%></span>
<% } %> <% } %>
<span id="sessionTimeoutTimer" style="display:block;font-size:10px;"></span>
</a></li> </a></li>
<li style="width:100px; line-height:80px; text-align:center;"> <li style="width:100px; line-height:80px; text-align:center;">
<select id="selectLocale" name="locale" style="width:60px; padding: 2px; text-align:center;"> <select id="selectLocale" name="locale" style="width:60px; padding: 2px; text-align:center;">
@@ -387,7 +387,7 @@
<div class="content_middle" id="content_middle"> <div class="content_middle" id="content_middle">
<div class="search_wrap"> <div class="search_wrap">
<button type="button" class="cssbtn" id="btn_download" level="W" status="DETAIL"><i class="material-icons">cloud_download</i> 이관</button> <button type="button" class="cssbtn" id="btn_download" level="W" status="DETAIL"><i class="material-icons">cloud_download</i> 이관</button>
<button type="button" class="cssbtn" id="btn_deploy" level="W" status="DETAIL"><i class="material-icons">cloud_upload</i> 배포</button> <!-- <button type="button" class="cssbtn" id="btn_deploy" level="W" status="DETAIL"><i class="material-icons">cloud_upload</i> 배포</button> -->
<button type="button" class="cssbtn" id="btn_import" level="R" data-bs-toggle="modal" <button type="button" class="cssbtn" id="btn_import" level="R" data-bs-toggle="modal"
data-bs-target="#uploadModal"><i data-bs-target="#uploadModal"><i
class="material-icons">upload</i> <%=localeMessage.getString("button.import")%> class="material-icons">upload</i> <%=localeMessage.getString("button.import")%>
@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import com.eactive.eai.rms.common.acl.menu.ui.LeftMenuUI; import com.eactive.eai.rms.common.acl.menu.ui.LeftMenuUI;
import com.eactive.eai.rms.common.acl.role.RoleManService; import com.eactive.eai.rms.common.acl.role.RoleManService;
import com.eactive.eai.rms.common.base.BaseAnnotationController; import com.eactive.eai.rms.common.base.BaseAnnotationController;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder; import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.login.SessionManager; import com.eactive.eai.rms.common.login.SessionManager;
import com.eactive.eai.rms.data.entity.man.menu.MenuService; import com.eactive.eai.rms.data.entity.man.menu.MenuService;
@@ -31,6 +32,9 @@ public class MenuRenderController extends BaseAnnotationController {
@Autowired @Autowired
private MenuRenderService menuRenderService; private MenuRenderService menuRenderService;
@Autowired
private MonitoringContext monitoringContext;
@GetMapping("/left_top.do") @GetMapping("/left_top.do")
public String left_top(HttpServletRequest request, ModelMap modelMap) { public String left_top(HttpServletRequest request, ModelMap modelMap) {
return "/common/screen/left_top"; return "/common/screen/left_top";
@@ -87,6 +91,9 @@ public class MenuRenderController extends BaseAnnotationController {
List<DataSourceType> roleServiceTypeList = roleManService.selectRoleServiceTypeList(roleIds); List<DataSourceType> roleServiceTypeList = roleManService.selectRoleServiceTypeList(roleIds);
modelMap.addAttribute("roleServiceTypeList", roleServiceTypeList); modelMap.addAttribute("roleServiceTypeList", roleServiceTypeList);
modelMap.addAttribute("autoLogoutTimeout",
monitoringContext.getIntProperty(MonitoringContext.RMS_AUTO_LOGOUT_TIMEOUT, 30));
if (StringUtils.isNotBlank(mainPage)) { if (StringUtils.isNotBlank(mainPage)) {
for (Map<String, Object> map : dataList) { for (Map<String, Object> map : dataList) {
String url = (String) map.get("LEV4_URL"); String url = (String) map.get("LEV4_URL");
@@ -694,7 +694,7 @@ public class MainController implements InterceptorSkipController {
model.addAttribute("mainPage", mainPage); model.addAttribute("mainPage", mainPage);
model.addAttribute("menuId", menuId); model.addAttribute("menuId", menuId);
model.addAttribute("autoLogoutTimeout", model.addAttribute("autoLogoutTimeout",
monitoringContext.getIntProperty(MonitoringContext.RMS_AUTO_LOGOUT_TIMEOUT, 60)); monitoringContext.getIntProperty(MonitoringContext.RMS_AUTO_LOGOUT_TIMEOUT, 30));
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("CURRENT SERVICE TYPE : " + service); logger.debug("CURRENT SERVICE TYPE : " + service);