초기소스

This commit is contained in:
jazz
2025-10-29 17:08:05 +09:00
parent e531aa9540
commit 439a379a02
7551 changed files with 1234427 additions and 3 deletions

View File

@@ -0,0 +1,135 @@
package com.wb.domainserver.interceptor.mngr;
import com.wb.domainserver.domain.auth.service.AuthService;
import com.wb.domainserver.domain.auth.vo.AuthVO;
import com.wb.domainserver.realm.RealmContextHolder;
import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import com.wb.domainserver.util.CookieUtils;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.util.List;
public class MngrAuthInterceptor implements HandlerInterceptor{
private static final Logger logger = LoggerFactory.getLogger(MngrAuthInterceptor.class);
@Autowired
private AuthService authService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod handlerMethod)) {
return true;
}
//쿠키 쇼핑몰 코드 조회
String cookieAuthSopmalCd = CookieUtils.getCookieValue("authSopmalCd", request);
//쿠키 쇼핑몰 코드 없을 경우 쿠키 생성 및 쇼핑몰코드 변수저장
if(!StringUtils.hasText(cookieAuthSopmalCd)){
//통합관리자인경우
if("ADMIN".equals(RealmContextHolder.getSopmalCdRealm())){
CookieUtils.createCookie("authSopmalCd", "SYS", "/admin", true, request, response);
cookieAuthSopmalCd = "SYS";
}else{
CookieUtils.createCookie("authSopmalCd", RealmContextHolder.getSopmalCdRealm(), "/mngr", true, request, response);
cookieAuthSopmalCd = RealmContextHolder.getSopmalCdRealm();
}
}
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
//관리자 권한 조회
boolean authChk = mngrAuthChk(request, response, user);
//해당 페이지에 접근권한이 없으면 alert
boolean result = false;
if(authChk){
AuthVO authVO = new AuthVO();
authVO.setMngrInnb(user.getUserInnb());
authVO.setSopmalCd(cookieAuthSopmalCd);
authVO.setSysDvCd(user.getSysDvCd());
String url = request.getRequestURI();
authVO.setFnctUri(url.equals("/") ? url + RealmContextHolder.getRealm().toLowerCase() : url);
// if("itrnt".equalsIgnoreCase(cookieAuthSopmalCd)){ //인트라넷 일 경우
// authVO.setStrOperDv(user.getStrOperDv());
// authVO.setTentGroup(user.getTentGroup());
// authVO.setReprsntBrand(user.getReprsntBrand());
//
// result = authService.selectItrntAuthorSiteAt(authVO);
// }else{
//관리자 + 통합관리자 일 경우
result = authService.selectAuthorSiteAt(authVO);
// }
}
if(!result){
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("<script>alert('해당페이지에 접근 권한이 없습니다. 관리자에게 문의하세요.'); window.history.back();</script>");
response.getWriter().flush();
return false;
}
return true;
}
/**
* 업무관리자 쇼핑몰 권한 조회
* @param request req
* @param response res
* @param user 유저정보
*/
private boolean mngrAuthChk(HttpServletRequest request, HttpServletResponse response, AnonymousUser user){
//권한 리스트 조회
AuthVO authVO = new AuthVO();
authVO.setMngrInnb(user.getUserInnb());
List<String> sopmalList = authService.selectAuthorSopmalList(authVO);
logger.debug("sopmalList {}", sopmalList);
//로그인 요청 쇼핑몰 param 조회
String queryString = request.getParameter("authSopmalCd");
logger.debug("authSopmalCd param :: {}", queryString);
//권한 리스트에 로그인 요청 쇼핑몰 param이 포함되면
String authSopmalCd = "";
if (!StringUtil.isEmpty(queryString) && sopmalList.contains(queryString)) {
// 로그인 요청 쇼핑몰 param 저장
authSopmalCd = queryString;
} else {
//쿠키에 권한 리스트중 첫번째 쇼핑몰 param 저장
if(!sopmalList.isEmpty()){
authSopmalCd = sopmalList.get(0);
}else{
return false;
}
}
CookieUtils.createCookie("authSopmalCd", authSopmalCd, "/mngr", true, request, response);
return true;
}
}

View File

@@ -0,0 +1,410 @@
package com.wb.domainserver.interceptor.mngr;
import com.wb.domainserver.domain.log.service.LogService;
import com.wb.domainserver.domain.log.vo.MngrAccessLogVo;
import com.wb.domainserver.interceptor.wrapper.MultipleReadableRequestWrapper;
import com.wb.domainserver.realm.util.UrlExtractor;
import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
public class MngrLoggingInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(MngrLoggingInterceptor.class);
@Autowired
private LogService logService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//기기식별번호 쿠키 생성
String agentId = agentIdHandleCookie(request, response);
// 래핑된 요청 객체 생성
HttpServletRequest wrappedRequest = new MultipleReadableRequestWrapper(request);
//관리자 접근로그 등록
insertMngrAccessLog(wrappedRequest, response, handler, agentId);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// if (handler instanceof HandlerMethod handlerMethod) {
//
// ContentCachingResponseWrapper responseWrapper = null;
// if(response instanceof ContentCachingResponseWrapper) {
// responseWrapper = (ContentCachingResponseWrapper) response;
// } else{
//
// responseWrapper = new ContentCachingResponseWrapper(response);
// }
// 캐싱된 바이트 배열을 UTF-8로 변환하여 반환
// String responseWrapperResult = new String(responseWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
// logger.debug("responseWrapper ::: {}", responseWrapperResult);
// }
}
/**
* 관리자 접속 로그 등록 함수
* @param logVo
* @return void
*/
private void insertMngrAccessLog(HttpServletRequest request, HttpServletResponse response, Object handler, String agentId) throws IOException {
if (handler instanceof HandlerMethod handlerMethod) {
//호출 서비스 정보
// 컨트롤러 클래스 이름
String controllerName = handlerMethod.getBeanType().getSimpleName();
// 호출된 메소드 이름
String methodName = handlerMethod.getMethod().getName();
// logger.debug("controllerName :: {} methodName :: {} ", controllerName, methodName);
//요청 URL
String url = request.getRequestURI();
// logger.debug("url :: {}", url);
/*관리자 로그 파라미터 지정 url */
String postParam =""; // POST 데이터 읽기
String getParam =""; //GET 데이터 읽기
if(url.contains("/mngr/mbr") //관리자 - 회원
|| url.contains("/mngr/setup/nbkk") // 관리자 - 설정 - 무통장
|| url.contains("/crm/mbr") // CRM - 회원수정, 조회 등
|| url.contains("/crm/dlvylc")){ //CRM - 회원배송지
if ("POST".equalsIgnoreCase(request.getMethod())) {
if("application/json".equalsIgnoreCase( request.getContentType())){
postParam = new String(request.getInputStream().readAllBytes(), request.getCharacterEncoding());
// logger.debug("POST json Data: {}", postParam);
}else{
postParam = getParameterMap(request);
// logger.debug("POST other Data: {}", postParam);
}
}
//get 쿼리스트링
getParam = request.getQueryString();
}
// Controller 정보, Client IP, Headers 등 추가적인 로직 처리 가능
//cookie agentId
// logger.debug("agentId :: {} ", agentId);
//agent 정보
String userAgent = request.getHeader("User-Agent");
// logger.debug("userAgent :: {}", userAgent);
//request referer 정보 확인
String referer = request.getHeader("Referer");
// logger.debug("Referer :: {}", referer);
//ip 정보
String clientIp = request.getHeader("X-Forwarded-For");
if (!StringUtil.isEmpty(clientIp) && clientIp.contains(",")) {
clientIp = clientIp.split(",")[0];
}
if (StringUtil.isEmpty(clientIp)) {
clientIp = request.getRemoteAddr();
}
// logger.debug("clientIp :: {}", clientIp);
request.setAttribute("LoggingClientIp", clientIp);
//host 정보
String host = request.getHeader("X-Original-Host") != null ? request.getHeader("X-Original-Host") : UrlExtractor.getOriginalHost(request);
// logger.debug("host :: {}", host);
//sessionId 정보
String jSessionId = "";
if(request.getCookies() != null){
for(Cookie cookie : request.getCookies()){
if(cookie.getName().equals("JSESSIONID")){
jSessionId = cookie.getValue();
break;
}
}
}
// logger.debug("jSessionId :: {}", jSessionId);
//서버 이름
String serverName = request.getServerName();
// logger.debug("serverName :: {}", serverName);
//접속환경
String env;
String upperUseAgent = userAgent.toUpperCase();
if (upperUseAgent.contains("MOBILE") || upperUseAgent.contains("ANDROID") || upperUseAgent.contains("IPHONE")) {
env = "MO";
} else if (upperUseAgent.contains("TABLET") || upperUseAgent.contains("IPAD")) {
env = "MO";
} else {
env = "PC";
}
request.setAttribute("env", env);
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
//고유 번호 등 개인식별 번호 확인
// logger.debug("sopmalCd :::: {}",user.getSopmalCd());
// logger.debug("userInnb :::: {}", user.getUserInnb());
// logger.debug("MbrDvCd :::: {}", user.getMbrDvCd());
//로그인 하였을 경우 url
// logger.debug("accessUrl :::: {}", user.getAccessUrl());
// logger.debug("clientId :::: {}", user.getClientId());
//접속 log insert
MngrAccessLogVo logVo = new MngrAccessLogVo();
logVo.setAgentId(agentId);
logVo.setSesionId(jSessionId);
String userMngrTy = user.getSopmalCd();
String mngrTy = "";
if("mngr".equalsIgnoreCase(userMngrTy)){ //관리자
mngrTy = "01";
}
if ("sys".equalsIgnoreCase(userMngrTy)){ // 통합관리자
mngrTy = "03";
}
if("itrnt".equalsIgnoreCase(userMngrTy)){// 인트라넷
mngrTy = "02";
}
logVo.setMngrTyCd(mngrTy);
logVo.setMngrInnb(user.getUserInnb());
String authSopmalCd = "";
//관리자 메인 진입시 쇼핑몰 선택했을 경우(로그인시)
if( "/mngr/main".equals(request.getRequestURI()) && !StringUtil.isEmpty(request.getParameter("authSopmalCd"))){
authSopmalCd = request.getParameter("authSopmalCd");
}
//이후 사이트 이동시
if(request.getCookies() != null){
for(Cookie cookie : request.getCookies()){
if(cookie.getName().equals("authSopmalCd")){
authSopmalCd = cookie.getValue();
break;
}
}
}
logVo.setSopmalCd(authSopmalCd);
//메뉴 정보
String[] menu = url.split("/"); // URL 추출
String menuDepth1 = "";
String menuDepth2 = "";
String menuDepth3 = "";
String menuDepth4 = "";
for(int i = 0; i < menu.length; i++){
if(i ==1){
menuDepth1 = menu[i];
}
if(i ==2){
menuDepth2 = menu[i];
}
if(i ==3){
menuDepth3 = menu[i];
}
if(i ==4){
menuDepth4 = menu[i];
}
}
// logger.debug("menuDepth1 :: {}", menuDepth1);
// logger.debug("menuDepth2 :: {}", menuDepth2);
// logger.debug("menuDepth3 :: {}", menuDepth3);
// logger.debug("menuDepth4 :: {}", menuDepth4);
logVo.setMenuGroup(menuDepth1);
logVo.setMenu(menuDepth2);
//로그 타입
String logType = "";
//멤버 조회시(MEMBER)
if("mbr".equals(menuDepth2)){
logType = "01";
//회원검색목록 폼 조회(MEMBERLIST)
if(menuDepth3.contains("selectMbrListInqire")){
logType = "02";
}
} else if ("ordr".equals(menuDepth2)) {
//주문 상세(ORDER)
if("selectOrdrDtlInqire".equals(menuDepth4)){
logType = "03";
}
//주문내역서 팝업 화면 이동 (주문내역 프린트 ORDERPRINT)
if("selectOrdrDtstmnDwldPopupForm".equals(menuDepth4)){
logType = "04";
}
//(주문목록) 엑셀다운로드(ORDEREXCEL)
if("selectExcelDwldListInqire".equals(menuDepth4)){
logType = "08";
}
// 출고 상세(EXPORT)
if("selectDlivyDtlInqire".equals(menuDepth4)){
logType = "05";
}
//출고내역서 팝업 화면 이동 (출고내역 프린트 EXPORTPRINT)
if("selectDlivyDtstmnDwldPopupForm".equals(menuDepth4)){
logType = "10";
}
//반품환불 상세 조회 (REFUND)
if("selectRtngudRefndDtlInqire".equals(menuDepth4)){
logType = "06";
}
}
logVo.setConectLogDvCd(logType);
logVo.setReqstMth(methodName);
logVo.setIp(clientIp);
logVo.setConectEnvrnDv(env);
logVo.setConectDomn(host);
logVo.setConectUrl(url);
logVo.setReqstData(!StringUtil.isEmpty(postParam)?postParam:getParam);
// logger.debug("logging interceptor logVO :::: {}", logVo );
logService.insertMngrAccessLog(logVo);
}
}
/**
* 기기식별번호 쿠키 생성 함수
* @param request
* @return agentId
*/
private String agentIdHandleCookie(HttpServletRequest request, HttpServletResponse response) throws NoSuchAlgorithmException {
String agentId = "";
//agentId 쿠키 있을 경우 가져옴
if (request.getCookies() != null) {
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("agent_id")) {
agentId = cookie.getValue();
break;
}
}
}
// 기존 agentId가 없을경우, 새로 발급
if (StringUtil.isEmpty(agentId)) {
//난수 생성
SecureRandom random = SecureRandom.getInstanceStrong();
random.setSeed(System.currentTimeMillis());
agentId = String.valueOf(System.currentTimeMillis());
String host = request.getHeader("X-Forwarded-Host");
if (host == null) {
host = request.getServerName(); // 기본값으로 현재 요청의 호스트명 사용
}
String domain = UrlExtractor.getOriginalHost(host);
String cookieValue = agentId + ":" + md5(agentId + ":" + md5(System.currentTimeMillis() + ":" + random.nextInt())).substring(5, 10);
Cookie agentIdCookie = new Cookie("agent_id", cookieValue);
agentIdCookie.setMaxAge(86400 * 365 * 10); // 10년
agentIdCookie.setDomain(domain);
// agentIdCookie.setHttpOnly(true);
agentIdCookie.setPath("/mngr");
// agentIdCookie.setSecure(true);
response.addCookie(agentIdCookie);
agentId = cookieValue;
}
return agentId;
}
/*쿠키 MD5 생성 함수 */
private String md5(String input) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes());
return Base64.getEncoder().encodeToString(digest);
}
/** 특정 쿠키 삭제(메뉴 클릭시에만 메뉴조회되게 하기 위해서) */
private void deleteCookie(HttpServletResponse res, String CookieId){
Cookie cookie = new Cookie(CookieId, null); // 삭제할 쿠키에 대한 값을 null로 지정
cookie.setMaxAge(0); // 유효시간을 0으로 설정해서 바로 만료시킨다.
res.addCookie(cookie); // 응답에 추가해서 없어지도록 함
}
// json 요청이 아닌 post 요청에서 파라미터를 Map으로 변환하는 메서드
private String getParameterMap(HttpServletRequest request) {
Map<String, String> paramMap = new HashMap<>();
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String paramName = parameterNames.nextElement();
String paramValue = request.getParameter(paramName);
paramMap.put(paramName, paramValue);
}
return paramMap.toString();
}
}

View File

@@ -0,0 +1,277 @@
package com.wb.domainserver.interceptor.mngr;
import com.wb.domainserver.domain.admin.sys.author.service.BOMaAuthorService;
import com.wb.domainserver.domain.admin.sys.author.vo.BOMaAuthorVO;
import com.wb.domainserver.domain.admin.sys.menu.service.BOMaMenuService;
import com.wb.domainserver.domain.admin.sys.menu.vo.BOMaMenuVO;
import com.wb.domainserver.domain.gcone.mbr.mbr.service.BOMbrService;
import com.wb.domainserver.domain.gcone.mbr.mbr.vo.BOMbrVO;
import com.wb.domainserver.realm.RealmContextHolder;
import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.Map;
public class MngrMenuInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(MngrMenuInterceptor.class);
@Autowired
private BOMaMenuService menuService;
@Autowired
private BOMaAuthorService boMaAuthorService;
@Autowired
private BOMbrService service;
// controller로 보내기 전에 처리하는 인터셉터
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String accessUri = request.getRequestURI(); // 현재 요청된 URI
AnonymousUser mngr = MemberJwtContextHolder.getMemberInfo();
String mngrDv = mngr.getMngrDv();
// 헤더의 사용자 이름을 표시하기 위해
String sysDvCd = mngr.getSysDvCd();
String userNm = "";
String itrntDv = "";
//인트라넷 분기처리
if("04".equals(sysDvCd)){
userNm = mngr.getTentcpnNm();
itrntDv = mngr.getItrntDv();
logger.info("MenuInterceptor itrntDv: {}", itrntDv);
}else{
userNm = mngr.getMbrNm();
}
request.setAttribute("userNm", userNm);
request.setAttribute("itrntDv", itrntDv);
// String accessUri = request.getRequestURI(); // 현재 요청된 URI
/** 메뉴 영역 조회 시작 **/
int firstSlashIndex = accessUri.indexOf('/');
int secondSlashIndex = accessUri.indexOf('/', firstSlashIndex + 1);
String systemType = "";
if(!isAjaxRequest(request)) {
// 시스템 구분 : 첫 번째 '/'와 두 번째 '/' 사이의 문자열을 추출
if (firstSlashIndex != -1 && secondSlashIndex != -1 && firstSlashIndex + 1 < secondSlashIndex) {
systemType = accessUri.substring(firstSlashIndex + 1, secondSlashIndex);
logger.info("Extracted system type: {}", systemType);
} else {
systemType = accessUri.substring(firstSlashIndex + 1);
logger.info("Could not find the substring between the first and second slashes.");
}
request.setAttribute("systemType", systemType);
// if(authorizationUrlChecker(systemType)){
// response.setContentType("text/html; charset=UTF-8");
// response.getWriter().write("<script>alert('허용되지 않는 요청입니다.'); location.href='/" + UrlExtractor.getSystemType() + "/main';</script>");
// response.getWriter().flush();
// return false;
// }
}
// 메뉴 클릭여부 체크
String checkMenu = null;
Cookie[] checkMenuCookies = request.getCookies();
if (checkMenuCookies != null) {
for (Cookie cookie : checkMenuCookies) {
if ("checkMenu".equals(cookie.getName())) {
checkMenu = cookie.getValue();
break;
}
}
}
if("/mngr/main".equals(accessUri) || "/admin/main".equals(accessUri) || accessUri.contains("/crm") || accessUri.contains("/itrnt")) {
checkMenu = "Y";
}
// FORM 호출 이후 ajax로 list호출될경우 메뉴 조회 할수 없는 case 방지
if(!isAjaxRequest(request)) {
if(!StringUtil.isEmpty(checkMenu) && "Y".equals(checkMenu)) {
// 통합관리자, 관리자
if("admin".equals(systemType) || "mngr".equals(systemType) || "crm".equals(systemType) || "itrnt".equals(systemType)) {
BOMaMenuVO vo = new BOMaMenuVO();
vo.setUrl(accessUri);
// 사용자가 선택한 URL 정보를 통해 TOP메뉴의 MENU_CD 조회
// 통합관리자
if("admin".equals(systemType)){
vo.setSopmalCd("SYS");
vo.setUpmostMenuCd("sys");
vo.setTopMenuCd("1");
vo.setNextDeptCd1("2");
vo.setNextDeptCd2("3");
// 관리자
}else if("mngr".equals(systemType)){
String cookieAuthSopmalCd = "";
//관리자 메인 진입시 쇼핑몰 선택했을 경우(로그인시)
if( "/mngr/main".equals(request.getRequestURI()) && !StringUtil.isEmpty(request.getParameter("authSopmalCd"))){
cookieAuthSopmalCd = request.getParameter("authSopmalCd");
}
if (request.getCookies() != null) {
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies) {
if("authSopmalCd".equals(cookie.getName())){
cookieAuthSopmalCd = cookie.getValue();
break;
}
}
}
if(!StringUtils.hasText(cookieAuthSopmalCd)){
cookieAuthSopmalCd = RealmContextHolder.getSopmalCdRealm();
}
vo.setSopmalCd(cookieAuthSopmalCd);
vo.setUpmostMenuCd("adm");
vo.setTopMenuCd("2");
vo.setNextDeptCd1("3");
vo.setNextDeptCd2("4");
//crm
}else if("crm".equals(systemType) ){
vo.setSopmalCd("CM");
vo.setUpmostMenuCd("crm");
}
//인트라넷
else{
vo.setSopmalCd("ITRNT");
vo.setUpmostMenuCd("itrnt");
vo.setTopMenuCd("1");
vo.setNextDeptCd1("2");
vo.setNextDeptCd2("3");
}
if(!"crm".equals(systemType)){
// Top에서 사용자가 선택한 menuCd와 URL정보를 Cookie에서 가져오기
String topMenuCd = null;
String leftMenuCd = null;
String upperMenuCd = null;
String topMenuUrl = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("topMenuCd".equals(cookie.getName())) {
topMenuCd = cookie.getValue();
} else if ("leftMenuCd".equals(cookie.getName())) {
leftMenuCd = cookie.getValue();
} else if ("topMenuUrl".equals(cookie.getName())) {
topMenuUrl = cookie.getValue();
} else if ("upperMenuCd".equals(cookie.getName())) {
upperMenuCd = cookie.getValue();
}
if (leftMenuCd != null && topMenuCd != null && upperMenuCd != null && topMenuUrl != null) {
break;
}
}
}
request.getSession().setAttribute("topMenuCd", topMenuCd);
request.getSession().setAttribute("leftMenuCd", leftMenuCd);
request.getSession().setAttribute("upperMenuCd", upperMenuCd);
request.getSession().setAttribute("topMenuUrl", topMenuUrl);
//TOP 메뉴 조회
Map<String, Object> topMenuMap = new HashMap<>();
topMenuMap.put("menuList", menuService.selectBOTopMenuListInqire(vo));
request.setAttribute("topMenuList", topMenuMap);
//LEFT 메뉴 조회
if (!StringUtil.isEmpty(topMenuCd)) {
vo.setUpperMenuCd(topMenuCd);
vo.setTopMenuCd("2");
Map<String, Object> leftMenuMap = new HashMap<>();
leftMenuMap.put("menuList", menuService.selectBOTopMenuListInqire(vo));
request.setAttribute("leftMenuList", leftMenuMap);
}
}else{
//crm 메뉴 조회
Map<String, Object> crmMenuList = new HashMap<>();
crmMenuList.put("menuList", menuService.selectBOCrmMenuListInqire(vo));
request.setAttribute("crmMenuList", crmMenuList);
}
if( "crm".equals(systemType) || "itrnt".equals(systemType)){
request.setAttribute("accessUri", accessUri);
}
//권한 있는 사이트 조회
if ("mngr".equalsIgnoreCase(systemType)||"crm".equalsIgnoreCase(systemType)) {
Map<String, Object> siteList = new HashMap<>();
BOMaAuthorVO boMaAuthorVO = new BOMaAuthorVO();
boMaAuthorVO.setMngrInnb(String.valueOf(mngr.getUserInnb()));
//권한에 있는 쇼핑몰만 조회
siteList.put("siteList", boMaAuthorService.selectBOAuthorSiteList(boMaAuthorVO));
request.setAttribute("siteList", siteList.get("siteList"));
}
request.setAttribute("isAuthenticated", isAuthenticated());
deleteCookie(response, "checkMenu");
}
}
}
/** 메뉴 영역 조회 종료 **/
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/** Ajax 여부 확인 */
private boolean isAjaxRequest(HttpServletRequest req) {
String header = req.getHeader("x-requested-with");
if ("XMLHttpRequest".equals(header)){
return true;
}else{
return false;
}
}
/** 특정 쿠키 삭제(메뉴 클릭시에만 메뉴조회되게 하기 위해서) */
public void deleteCookie(HttpServletResponse res, String CookieId){
Cookie cookie = new Cookie(CookieId, null); // 삭제할 쿠키에 대한 값을 null로 지정
cookie.setMaxAge(0); // 유효시간을 0으로 설정해서 바로 만료시킨다.
res.addCookie(cookie); // 응답에 추가해서 없어지도록 함
}
/** 로그인 여부 체크 */
private boolean isAuthenticated() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || authentication instanceof AnonymousAuthenticationToken) {
return false;
}
return authentication.isAuthenticated();
}
}

View File

@@ -0,0 +1,75 @@
package com.wb.domainserver.interceptor.sopmal;
import com.wb.domainserver.domain.auth.service.AuthService;
import com.wb.domainserver.domain.auth.vo.AuthVO;
import com.wb.domainserver.realm.RealmContextHolder;
import com.wb.domainserver.realm.util.UrlExtractor;
import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
@Slf4j
public class AuthInterceptor implements HandlerInterceptor {
@Autowired
private AuthService service;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod handlerMethod) {
String uri = request.getRequestURI();
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
String sysDvCd = user.getSysDvCd();
String[] menu = uri.split("/"); // URL 추출
String menuDepth1 = "";
for (int i = 0; i < menu.length; i++) {
if (i == 1) {
menuDepth1 = menu[i];
}
}
log.debug("menuDepth1 :: {}", menuDepth1);
//사용자 권한 조회는 메뉴 1뎁스만 조회 비교
AuthVO vo = new AuthVO();
vo.setUri("/" + menuDepth1);
// /*사용자 권한 조회*/
// if("01".equals(sysDvCd)){
// Map<String, Object> auth = service.selectUserAuthor(vo);
// if("N".equals(auth.get("authAt"))){
//
// throw new WnbtException(ErrCode.PAGE_NOT_FOUND);
//
// }
// }
String host = request.getHeader("X-Forwarded-Host");
if (host == null) {
host = request.getServerName(); // 기본값으로 현재 요청의 호스트명 사용
}
String domain = UrlExtractor.getOriginalHost(host);
Cookie authSopmalCdCookie = new Cookie("authSopmalCd",RealmContextHolder.getSopmalCdRealm());
authSopmalCdCookie.setHttpOnly(true);
// authSopmalCdCookie.setDomain(domain);
authSopmalCdCookie.setPath("/sopmal");
response.addCookie(authSopmalCdCookie);
}
return true;
}
}

View File

@@ -0,0 +1,38 @@
package com.wb.domainserver.interceptor.sopmal;
import com.wb.domainserver.realm.util.UrlExtractor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
public class DeviceHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String userAgent = request.getHeader("User-Agent").toLowerCase();
String deviceType = "desktop";
String originalHost = request.getHeader("X-Original-Host") != null ? request.getHeader("X-Original-Host") : UrlExtractor.getOriginalHost(request);
String systemDv = "sopmal";
if(originalHost.contains("mngr.alleyslab")){
systemDv = "mngr";
}
// 모바일
if (userAgent.contains("mobile") || userAgent.contains("android") || userAgent.contains("iphone")) {
deviceType = systemDv+"_m";
// 테블릿
} else if (userAgent.contains("tablet") || userAgent.contains("ipad")) {
deviceType = systemDv+"_m";
// PC
} else {
if (originalHost.startsWith("m.")) {
deviceType = systemDv+"_m";
} else {
deviceType = systemDv;
}
}
//관리자 모바일 환경 체크
request.setAttribute("deviceType", deviceType);
return true;
}
}

View File

@@ -0,0 +1,52 @@
package com.wb.domainserver.interceptor.sopmal;
import com.wb.domainserver.domain.admin.store.sopmal.service.BOMaSopmalService;
import com.wb.domainserver.domain.admin.store.sopmal.vo.BOMaSopmalVO;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.Map;
public class FooterInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(FooterInterceptor.class);
@Autowired
private BOMaSopmalService sopmalService;
// controller로 보내기 전에 처리하는 인터셉터
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (!isAjaxRequest(request)) {
//footer 정보 조회
BOMaSopmalVO vo = new BOMaSopmalVO();
vo.setSopmalCd(MemberJwtContextHolder.getMemberInfo().getSopmalCd());
Map<String,Object> footerInfo = new HashMap<>();
footerInfo.put("footerInfo", sopmalService.selectBOSopmalFooterInfo(vo));
request.setAttribute("footerInfo", footerInfo);
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
private boolean isAjaxRequest(HttpServletRequest req) {
String header = req.getHeader("x-requested-with");
if ("XMLHttpRequest".equals(header)){
return true;
}else{
return false;
}
}
}

View File

@@ -0,0 +1,342 @@
package com.wb.domainserver.interceptor.sopmal;
import com.wb.domainserver.domain.log.service.LogService;
import com.wb.domainserver.domain.log.vo.AccessLogVO;
import com.wb.domainserver.interceptor.wrapper.MultipleReadableRequestWrapper;
import com.wb.domainserver.realm.util.UrlExtractor;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
public class LoggingInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
@Autowired
private LogService logService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//기기식별번호 쿠키 생성
logger.info("LoggingInterceptor :::: agentIdHandleCookie START");
String agentId = agentIdHandleCookie(request, response);
logger.info("LoggingInterceptor :::: agentIdHandleCookie END");
// 래핑된 요청 객체 생성
HttpServletRequest wrappedRequest = new MultipleReadableRequestWrapper(request);
//사용자 접근로그 등록
logger.info("LoggingInterceptor :::: insertAccessLog START");
insertAccessLog(wrappedRequest, response, handler, agentId);
logger.info("LoggingInterceptor :::: insertAccessLog END");
return true;
}
/**
* 사용자 접속 로그 등록 함수
* @return void
*/
private void insertAccessLog(HttpServletRequest request, HttpServletResponse response, Object handler, String agentId) throws IOException, URISyntaxException {
if (handler instanceof HandlerMethod handlerMethod) {
//호출 서비스 정보
// 호출된 메소드 이름
String methodName = handlerMethod.getMethod().getName();
// POST 데이터 읽기
String postParam ="";
if ("POST".equalsIgnoreCase(request.getMethod())) {
if("application/json".equalsIgnoreCase( request.getContentType())){
postParam = new String(request.getInputStream().readAllBytes(), request.getCharacterEncoding());
}else{
postParam = getParameterMap(request);
}
}
// Controller 정보, Client IP, Headers 등 추가적인 로직 처리 가능
//cookie agentId
//agent 정보
String userAgent = request.getHeader("User-Agent");
//request referer 정보 확인
String referer = request.getHeader("Referer");
HttpSession session = request.getSession();
if(!ObjectUtils.isEmpty(session.getAttribute("userReferer"))){
session.setAttribute("userReferer", referer);
}
//ip 정보
String clientIp = request.getHeader("X-Forwarded-For");
if (!StringUtil.isEmpty(clientIp) && clientIp.contains(",")) {
clientIp = clientIp.split(",")[0];
}
if (StringUtil.isEmpty(clientIp)) {
clientIp = request.getRemoteAddr();
}
//host 정보
String host = request.getHeader("X-Original-Host") != null ? request.getHeader("X-Original-Host") : UrlExtractor.getOriginalHost(request);
request.setAttribute("originalHost", host);
//sessionId 정보
String jSessionId = "";
String originalHost = "";
if(request.getCookies() != null) {
for(Cookie cookie : request.getCookies()){
if(cookie.getName().equals("JSESSIONID")){
jSessionId = cookie.getValue();
}
if(cookie.getName().equals("originalHost")){
originalHost = cookie.getValue();
}
}
}
if(!StringUtils.hasText(originalHost)){
Cookie hostcookie = new Cookie("originalHost",host);
hostcookie.setPath("/");
hostcookie.setMaxAge(1800);
response.addCookie(hostcookie);
}
//요청 URL
String url = request.getRequestURI();
//서버 이름
String serverName = request.getServerName();
//접속환경
String env ="";
String upperUseAgent = userAgent.toUpperCase();
if (upperUseAgent.contains("MOBILE") || upperUseAgent.contains("ANDROID") || upperUseAgent.contains("IPHONE")) {
env = "MO";
} else if (upperUseAgent.contains("TABLET") || upperUseAgent.contains("IPAD")) {
env = "MO";
} else {
env = "PC";
}
request.setAttribute("env", env);
//get 쿼리스트링
String getParam = request.getQueryString();
//접속 log insert
AccessLogVO logVo = new AccessLogVO();
logVo.setAgentId(agentId);
logVo.setSesionId(jSessionId);
logVo.setMbrInnb(MemberJwtContextHolder.getMemberInfo().getUserInnb());
logVo.setSopmalCd(MemberJwtContextHolder.getMemberInfo().getSopmalCd());
//메뉴 정보
String[] menu = url.split("/"); // URL 추출
String menuDepth1 = "";
String menuDepth2 = "";
for(int i = 0; i < menu.length; i++){
if(i ==1){
menuDepth1 = menu[i];
}
if(i ==2){
menuDepth2 = menu[i];
}
}
logVo.setMenuGroup(menuDepth1);
logVo.setMenu(menuDepth2);
logVo.setReqstMth(methodName);
String adTraceCd = "";
if(!StringUtil.isEmpty(getParam)){
Map<String, Object> getParamMap = new HashMap<>();
getParamMap = extractGcParams(getParam);
//광고유입코드
if(getParamMap.containsKey("_gc")){
request.setAttribute("adTraceCd", getParamMap.get("_gc").toString());
adTraceCd = getParamMap.get("_gc").toString();
}
//EP 코드
if(getParamMap.containsKey("market")){
request.setAttribute("epCd", getParamMap.get("market").toString());
}
}
logVo.setAdTraceCd(adTraceCd);
request.setAttribute("LoggingClientIp", clientIp);
logVo.setIp(clientIp);
logVo.setConectEnvrnDv(env);
logVo.setConectDomn(host);
logVo.setConectUrl(url);
logVo.setReqstData(!StringUtil.isEmpty(postParam)?postParam:getParam);
logVo.setReferer(referer);
String refererDomain = "";
//? 를 기준으로 referer domain 추출
if(!StringUtil.isEmpty(referer)){
URI uri = new URI(referer);
refererDomain = uri.getScheme()+"://"+uri.getHost();
}
logVo.setRefererDomn(refererDomain);
logService.insertAccessLog(logVo);
}
}
/**
* 기기식별번호 쿠키 생성 함수
* @param request
* @return agentId
*/
private String agentIdHandleCookie(HttpServletRequest request, HttpServletResponse response) throws NoSuchAlgorithmException {
String agentId = "";
String host = request.getHeader("X-Forwarded-Host");
if (host == null) {
host = request.getServerName(); // 기본값으로 현재 요청의 호스트명 사용
}
String domain = UrlExtractor.getOriginalHost(host);
//agentId 쿠키 있을 경우 가져옴
if (request.getCookies() != null) {
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("agent_id")) {
agentId = cookie.getValue();
}
}
}
// 기존 agentId가 없을경우, 새로 발급
if (StringUtil.isEmpty(agentId)) {
//난수 생성
SecureRandom random = SecureRandom.getInstanceStrong();
random.setSeed(System.currentTimeMillis());
agentId = String.valueOf(System.currentTimeMillis());
String cookieValue = agentId + ":" + md5(agentId + ":" + md5(System.currentTimeMillis() + ":" + random.nextInt())).substring(5, 10);
Cookie agentIdCookie = new Cookie("agent_id", cookieValue);
agentIdCookie.setMaxAge(86400 * 365 * 10); // 10년
// agentIdCookie.setHttpOnly(true);
agentIdCookie.setDomain(domain);
agentIdCookie.setPath("/");
// agentIdCookie.setSecure(true);
response.addCookie(agentIdCookie);
agentId = cookieValue;
}
//잘못 생성된 쿠키정보 삭제
deleteCookie(response, "agent_id", domain, "/sopmal");
return agentId;
}
/*쿠키 MD5 생성 함수 */
private String md5(String input) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes());
return Base64.getEncoder().encodeToString(digest);
}
/** 특정 쿠키 삭제(메뉴 클릭시에만 메뉴조회되게 하기 위해서) */
private void deleteCookie(HttpServletResponse res, String CookieId){
Cookie cookie = new Cookie(CookieId, null); // 삭제할 쿠키에 대한 값을 null로 지정
cookie.setMaxAge(0); // 유효시간을 0으로 설정해서 바로 만료시킨다.
res.addCookie(cookie); // 응답에 추가해서 없어지도록 함
}
/** 특정 쿠키 삭제(메뉴 클릭시에만 메뉴조회되게 하기 위해서) */
private void deleteCookie(HttpServletResponse res, String CookieId, String domain, String path){
Cookie cookie = new Cookie(CookieId, null); // 삭제할 쿠키에 대한 값을 null로 지정
cookie.setMaxAge(0); // 유효시간을 0으로 설정해서 바로 만료시킨다.
cookie.setDomain(domain);
cookie.setPath(path);
res.addCookie(cookie); // 응답에 추가해서 없어지도록 함
}
//queryString에서 광고유입코드 추출 함수
private Map<String, Object> extractGcParams(String queryString) {
Map<String, Object> gcParams = new HashMap<>();
// 쿼리 스트링을 '&'로 분리
if(queryString.contains("&")){
String[] pairs = queryString.split("&");
for (String pair : pairs) {
String[] keyValue = pair.split("=");
if (keyValue.length == 2) {
String key = keyValue[0];
String value = keyValue[1];
// _gc로 시작하는 키를 필터링하여 값 추출
if (key.startsWith("_gc")) {
gcParams.put(key, value);
}
// market으로 시작하는 키를 필터링하여 값 추출
if (key.startsWith("market")) {
gcParams.put(key, value);
}
}
}
}
return gcParams;
}
// json 요청이 아닌 post 요청에서 파라미터를 Map으로 변환하는 메서드
private String getParameterMap(HttpServletRequest request) {
Map<String, String> paramMap = new HashMap<>();
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String paramName = parameterNames.nextElement();
String paramValue = request.getParameter(paramName);
paramMap.put(paramName, paramValue);
}
return paramMap.toString();
}
}

View File

@@ -0,0 +1,190 @@
package com.wb.domainserver.interceptor.sopmal;
import com.wb.domainserver.common.prop.PropertyService;
import com.wb.domainserver.domain.frstlogin.service.FrstLoginService;
import com.wb.domainserver.domain.frstlogin.vo.FrstLoginVO;
import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Map;
public class LoginChkInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(LoginChkInterceptor.class);
@Autowired
private FrstLoginService service;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//최초 로그인시 처리 메서드
frstLoginChk(request, response);
HttpSession session = request.getSession();
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
//사용자 아이디 md5 생성 - 광고스크립트 용
String mbrId = "";
if(!StringUtil.isEmpty(user.getMbrId())){
mbrId = md5(user.getMbrId());
}
session.setAttribute("adscriptMbrId",mbrId );
return true;
}
/**
* 최초 로그인시 처리 메서드
* @param request
*/
private void frstLoginChk(HttpServletRequest request, HttpServletResponse response) throws NoSuchAlgorithmException {
HttpSession session = request.getSession();
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
int mbrInnb = user.getUserInnb();
//비회원 접속(비로그인 상태)
if(mbrInnb == 0){
session.setAttribute("loginAt", "N");
}
//회원접속 (로그인 상태)
if(mbrInnb > 0 && "N".equals(session.getAttribute("loginAt"))){
session.setAttribute("loginAt", "Y");
}
// 최초 로그인시
if(mbrInnb > 0 && "Y".equals(session.getAttribute("loginAt"))){
// 서비스 호출
FrstLoginVO frstLoginVO = new FrstLoginVO();
String sessionId = "";
if(request.getCookies()!= null){
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies){
if(cookie.getName().equals("JSESSIONID")){
sessionId = cookie.getValue();
break;
}
}
}
frstLoginVO.setSesionId(sessionId);
frstLoginVO.setMbrInnb(mbrInnb);
frstLoginVO.setMbrDvCd(user.getMbrDvCd());
frstLoginVO.setUpdusr(mbrInnb);
frstLoginVO.setSopmalCd(user.getSopmalCd());
//비회원 -> 회원 로그인시 회원 구매하기 상태 상품 제거
service.deletePurchsSpbkMbr(frstLoginVO);
//비회원 -> 회원 로그인시 장바구니 업데이트
service.updateSpbkSesionToMbr(frstLoginVO);
//비밀번호 재변경일 정책 월수
String passwordChngDe = PropertyService.getProperty("frstlogin.password.chngde."+user.getSopmalCd().toLowerCase());
//비밀번호 재확인일 정책 월수
String passwordCnfirmDe = PropertyService.getProperty("frstlogin.password.cnfirmde."+user.getSopmalCd().toLowerCase());
frstLoginVO.setPasswordChngDe(passwordChngDe);
frstLoginVO.setPasswordCnfirmDe(passwordCnfirmDe);
//비회원 -> 회원 로그인시 비밀번호 변경일 기준 6개월 경과 회원 여부
Map<String, Object> PasswordChngDeAt = service.selectPasswordChngDeAt(frstLoginVO);
Map<String, Object> shopmalNm = service.selectshopmalName(frstLoginVO);
if(PasswordChngDeAt.containsKey("chngDeAt")){
//비밀번호 변경 대상이면
if("Y".equals(PasswordChngDeAt.get("chngDeAt"))){
session.setAttribute("passwordChngDeAt", "Y");
session.setAttribute("passwordChngShopmalNm", shopmalNm.get("SOPMAL_NM"));
session.setAttribute("passwordChngDe", passwordChngDe);
session.setAttribute("passwordCnfirmDe", passwordCnfirmDe);
}
}
//로그인 상태이지만 최초로그인은 아닌 상태
session.setAttribute("loginAt", "P");
// 접속로그 등록 시작
//AgentId
Cookie[] cookies = request.getCookies();
String agentId = "";
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("agent_id")) {
agentId = cookie.getValue();
break;
}
}
}
frstLoginVO.setAgentId(agentId);
//ip 정보
String clientIp = request.getHeader("X-Forwarded-For");
if (!StringUtil.isEmpty(clientIp) && clientIp.contains(",")) {
clientIp = clientIp.split(",")[0];
}
if (StringUtil.isEmpty(clientIp)) {
clientIp = request.getRemoteAddr();
}
frstLoginVO.setIp(clientIp);
//접속환경
String env ="";
String userAgent = request.getHeader("User-Agent");
String upperUseAgent = userAgent.toUpperCase();
if (upperUseAgent.contains("MOBILE") || upperUseAgent.contains("ANDROID") || upperUseAgent.contains("IPHONE")) {
env = "MO";
} else if (upperUseAgent.contains("TABLET") || upperUseAgent.contains("IPAD")) {
env = "MO";
} else {
env = "PC";
}
frstLoginVO.setConectEnvrnDv(env);
//도메인
String serverName = request.getServerName();
frstLoginVO.setConectDomn(serverName);
frstLoginVO.setJoinMthCd(request.getHeader("X-JoinMthCd"));
try {
service.insertMemberLogin(frstLoginVO);
}catch (Exception e){
logger.debug("insertMemberLogin 에러 발생");
}
// 접속로그 등록 종료
/*마케팅 수신동의 여부 조회*/
//해당 쇼핑몰에 마케팅 수신동의받은 이력이 없으면
if(service.selectMemMarktAgree(frstLoginVO)){
Cookie marktAgree = new Cookie("marktAgreeAt","N");
marktAgree.setPath("/sopmal");
response.addCookie(marktAgree);
}
}
}
/*사용자 아이디 SHA-256 생성 함수 */
private static String md5(String input) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(input.getBytes());
return Base64.getEncoder().encodeToString(digest);
}
}

View File

@@ -0,0 +1,265 @@
package com.wb.domainserver.interceptor.sopmal;
import com.wb.domainserver.domain.comm.vo.MenuVO;
import com.wb.domainserver.domain.admin.store.sopmal.service.BOMaSopmalService;
import com.wb.domainserver.domain.admin.store.sopthema.service.BOSopthemaService;
import com.wb.domainserver.domain.admin.store.sopthema.vo.BOSopThemaVO;
import com.wb.domainserver.domain.admin.sys.author.service.BOMaAuthorService;
import com.wb.domainserver.domain.admin.sys.menu.service.BOMaMenuService;
import com.wb.domainserver.domain.admin.sys.menu.vo.BOMaMenuVO;
import com.wb.domainserver.domain.admin.user.mngr.service.BOMaMngrService;
import com.wb.domainserver.domain.gcone.common.service.BOCommonService;
import com.wb.domainserver.domain.gcone.setup.ordrmngr.mapper.BOOrdrMngrMapper;
import com.wb.domainserver.domain.gcone.setup.ordrmngr.vo.BOSetupOrdrVO;
import com.wb.domainserver.domain.gcone.setup.site.service.BOSiteService;
import com.wb.domainserver.domain.gcone.setup.site.vo.BOSiteVO;
import com.wb.domainserver.domain.sample.vo.PrevewVO;
import com.wb.domainserver.response.WnbtWebClientResponseHandler;
import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import com.wb.domainserver.util.communicate.SendToResrc;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
public class MenuInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(MenuInterceptor.class);
// @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
String issuerUri;
// 모든 요청 URI와 마지막 요청 시간을 저장할 맵
private Map<String, Long> requestTimestamps = new ConcurrentHashMap<>();
// 중복 요청을 허용하지 않을 시간 간격 (예: 1000밀리초 = 1초)
private static final long TIME_INTERVAL = 500;
@Autowired
private WnbtWebClientResponseHandler responseHandler;
@Autowired
private SendToResrc sendToResrc;
@Autowired
private BOCommonService service;
@Autowired
private BOMaMenuService menuService;
@Autowired
private BOMaSopmalService sopmalService;
@Autowired
private BOSopthemaService bOSopthemaService;
@Autowired
private BOOrdrMngrMapper ordrMngrMapper;
@Autowired
private BOSiteService boSiteService;
@Autowired
private BOMaMngrService mngrService;
@Autowired
private BOMaAuthorService boMaAuthorService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/** Request 중복 요청 처리 방지(더블클릭) 시작 */
String accessUri = request.getRequestURI(); // 현재 요청된 URI
/**
long currentTime = System.currentTimeMillis(); // 현재 시간
// 이전에 해당 URI로 요청한 시간이 있는지 확인
Long lastRequestTime = requestTimestamps.get(accessUri);
if (lastRequestTime != null) {
// 마지막 요청 시간과 현재 시간의 차이를 계산
long timeDiff = currentTime - lastRequestTime;
if (timeDiff < TIME_INTERVAL) {
// 요청 간격이 너무 짧다면 중복 요청으로 간주하고 무시
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getWriter().write("Duplicate request detected for URL: " + accessUri);
System.out.println("Duplicate request detected for URL: " + accessUri);
return false; // 요청 차단
}
}
// 중복 요청이 아니면 현재 시간을 저장하고 요청을 진행
requestTimestamps.put(accessUri, currentTime);
**/
/** Request 중복 요청 처리 방지(더블클릭) 종료 **/
/** 메뉴 영역 조회 시작 **/
// 메뉴 클릭여부 체크
String checkMenu = null;
Cookie[] checkMenuCookies = request.getCookies();
if (checkMenuCookies != null) {
for (Cookie cookie : checkMenuCookies) {
if ("checkMenu".equals(cookie.getName())) {
checkMenu = cookie.getValue();
break;
}
}
}
if("/index".equals(accessUri) || "/".equals(accessUri)) {
checkMenu = "Y";
}
MenuVO menuVO = new MenuVO();
if(!isAjaxRequest(request)) {
// if(!StringUtil.isEmpty(checkMenu) && "Y".equals(checkMenu)) {
menuVO.setUrl(accessUri);
menuVO.setSopmalCd(MemberJwtContextHolder.getMemberInfo().getSopmalCd());
// 마이페이지 선택한 카테고리ID
String ctgryId = "0";
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("ctgryId".equals(cookie.getName())) {
ctgryId = cookie.getValue();
}
}
}
request.getSession().setAttribute("ctgryId", ctgryId);
//쇼핑몰 테마용 접속환경 구분 저장
if(!ObjectUtils.isEmpty(request.getAttribute("env"))){
menuVO.setEnv(request.getAttribute("env").toString());
}
//TOP 메뉴, 쇼핑몰 정보 조회
Map<String, Object> sopmallInfo = new HashMap<>();
BOMaMenuVO boMaMenuVO = new BOMaMenuVO();
boMaMenuVO.setSopmalCd(menuVO.getSopmalCd());
// 메뉴정보 조회
sopmallInfo.put("menuList", menuService.selectBOSopmalTopMenuListInqire(boMaMenuVO));
// Shop 정보 조회
BOSetupOrdrVO boOrdrVO = new BOSetupOrdrVO();
boOrdrVO.setSopmalCd(menuVO.getSopmalCd());
sopmallInfo.put("shopInfo", ordrMngrMapper.selectBOOrdrSetup(boOrdrVO));
String sysDvCd = MemberJwtContextHolder.getMemberInfo().getSysDvCd();
//쇼핑몰 테마 조회
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
BOSopThemaVO boSopthemaVO = new BOSopThemaVO();
if("01".equals(sysDvCd)){
boSopthemaVO.setSopmalCd(user.getSopmalCd());
//접속환경이 비었으면
log.debug("환경 ?{}",menuVO.getEnv());
if("".equals(StringUtil.isNullToString(menuVO.getEnv()))){
boSopthemaVO.setEnv("MO"); //기본 MO 세팅
}else{
boSopthemaVO.setEnv(menuVO.getEnv());//접속환경 PC, MO
}
String themaPath = bOSopthemaService.selectBOSopThemaDtlInfo(boSopthemaVO);
sopmallInfo.put("themaPath", themaPath);
request.setAttribute("sopmallInfo", sopmallInfo);
request.setAttribute("accessUri", accessUri);
request.setAttribute("issuerUri", issuerUri);
// 세션 객체 가져오기
HttpSession session = request.getSession();
String sessionId = session.getId(); // 세션 아이디 가져오기
PrevewVO prevewVO = new PrevewVO();
//관리자 미리보기 선택시 넘어오는 값 바인딩
if(!StringUtil.isEmpty(request.getParameter("mainSiteInnb"))){
prevewVO.setMainSiteInnb(Integer.parseInt(request.getParameter("mainSiteInnb")));
}
prevewVO.setSessionId(sessionId);
// 헤더 영역, 인기 검색어, 실시간 인기 상품 정보 조회
BOSiteVO siteVO = new BOSiteVO();
siteVO.setSopmalCd(user.getSopmalCd()); // 쇼핑몰코드
siteVO.setSessionId(prevewVO.getSessionId());
siteVO.setMainSiteInnb(prevewVO.getMainSiteInnb());
Map<String, Object> topBarInfo = boSiteService.selectBOMainTopbarSiteDesignInqire(siteVO);
request.setAttribute("topBarInfo", topBarInfo);
// 쿠키 삭제
deleteCookie(response, "checkMenu");
}
}
// 로그인여부 체크
request.setAttribute("isAuthenticated", isAuthenticated());
/** 메뉴 영역 조회 종료 **/
return true;
}
/** Ajax 여부 확인 */
private boolean isAjaxRequest(HttpServletRequest req) {
String header = req.getHeader("x-requested-with");
if ("XMLHttpRequest".equals(header)){
return true;
}else{
return false;
}
}
/** 특정 쿠키 삭제(메뉴 클릭시에만 메뉴조회되게 하기 위해서) */
public void deleteCookie(HttpServletResponse res, String CookieId){
Cookie cookie = new Cookie(CookieId, null); // 삭제할 쿠키에 대한 값을 null로 지정
cookie.setMaxAge(0); // 유효시간을 0으로 설정해서 바로 만료시킨다.
res.addCookie(cookie); // 응답에 추가해서 없어지도록 함
}
private boolean isAuthenticated() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || authentication instanceof AnonymousAuthenticationToken) {
return false;
}
return authentication.isAuthenticated();
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
}

View File

@@ -0,0 +1,144 @@
package com.wb.domainserver.interceptor.sopmal;
import com.wb.domainserver.domain.oper.service.OperService;
import com.wb.domainserver.domain.oper.vo.OperVO;
import com.wb.domainserver.security.authentication.AnonymousUser;
import com.wb.domainserver.security.authentication.MemberJwtContextHolder;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.util.Map;
@Slf4j
public class OperInterceptor implements HandlerInterceptor {
@Autowired
private OperService service;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(handler instanceof HandlerMethod handlerMethod) {
AnonymousUser user = MemberJwtContextHolder.getMemberInfo();
OperVO vo = new OperVO();
vo.setSopmalCd(user.getSopmalCd());
String sysDvCd = user.getSysDvCd();
//사용자면 운영여부 체크
if("01".equals(sysDvCd)) {
Map<String, Object> oper = service.selectMainOperAt(vo);
//운영중이 아니면
if(!"Y".equals(oper.get("OPER_AT"))){
//접속환경 확인하여
String env = request.getAttribute("env").toString();
response.setContentType("text/html; charset=UTF-8");
response.setStatus(HttpServletResponse.SC_OK);
//해당 접속환경에 맞는 페이지 리턴
response.getWriter().write("PC".equalsIgnoreCase(env)?pcOperN(vo.getSopmalCd(), oper.get("RPLC_URL").toString()):mobileOperN(vo.getSopmalCd(),oper.get("RPLC_URL").toString()));
response.getWriter().flush();
return false;
}
}
}
return true;
}
/* 공사중 PC 버전 */
private String pcOperN(String sopmalCd, String rplcUrl) {
// 조건에 따라 리다이렉트 스크립트를 추가
String redirectScript = "";
// rplcUrl이 유효한 값일 경우에만 리다이렉트 실행
if (!rplcUrl.trim().isEmpty()) {
redirectScript =
"<script>" +
" setTimeout(function() {" +
" if (confirm(\"스마트스토어로 이동합니다.\")) {" +
" window.location.href = \"" + rplcUrl + "\";" +
" }" +
" }, 5000);" +
"</script>";
}
return "<!DOCTYPE html>" +
"<html lang=\"ko\">" +
"<head>" +
" <title>사이트 준비중</title>" +
" <link rel=\"stylesheet\" type=\"text/css\" href=\"/pc/css/default.css\">" +
redirectScript +
"</head>" +
"<body>" +
" <div class=\"wrap_error\">" +
" <div class=\"inner_error\">" +
" <img src=\"/pc/images/icon_maintenance.png\" alt=\"\">" +
" <p class=\"tit_error\">사이트 <em>준비 중</em>입니다.</p>" +
" <p class=\"desc_error\">" +
" 사이트에 방문을 환영합니다.<br>" +
" 홈페이지 공사중에 있습니다.<br>" +
" 빠른 시일내에 홈페이지를 오픈 하겠습니다.<br>" +
" 감사합니다.<br><br>" +
" </p>" +
" </div>" +
" </div>" +
"</body>" +
"</html>";
}
/* 공사중 모바일 버전 */
private String mobileOperN(String sopmalCd, String rplcUrl) {
// 조건에 따라 리다이렉트 스크립트를 추가
String redirectScript = "";
// rplcUrl이 유효한 값일 경우에만 리다이렉트 실행
if (rplcUrl != null && !rplcUrl.trim().isEmpty()) {
redirectScript =
"<script>" +
" setTimeout(function() {" +
" if (confirm(\"스마트스토어로 이동합니다.\")) {" +
" window.location.href = \"" + rplcUrl + "\";" +
" }" +
" }, 5000);" +
"</script>";
}
return "<!DOCTYPE html>" +
"<html lang=\"ko\">" +
"<head>" +
" <title>사이트 준비중</title>" +
" <link rel=\"stylesheet\" type=\"text/css\" href=\"/mobile/css/default.css\">" +
redirectScript +
"</head>" +
"<body>" +
" <div class=\"screen-wrap\">" +
" <div class=\"wrap_error\">" +
" <div class=\"inner_error\">" +
" <img src=\"/mobile/images/icon_maintenance.png\" alt=\"\">" +
" <p class=\"tit_error\">사이트 <em>준비 중</em>입니다.</p>" +
" <p class=\"desc_error\">" +
" 사이트에 방문을 환영합니다.<br>" +
" 홈페이지 공사중에 있습니다.<br>" +
" 빠른 시일내에 홈페이지를 오픈 하겠습니다.<br>" +
" 감사합니다.<br><br>" +
" </p>" +
" </div>" +
" </div>" +
" </div>" +
"</body>" +
"</html>";
}
}

View File

@@ -0,0 +1,56 @@
package com.wb.domainserver.interceptor.wrapper;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import org.apache.poi.util.IOUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class MultipleReadableRequestWrapper extends HttpServletRequestWrapper {
private byte[] cachedBody;
public MultipleReadableRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
// 요청 본문을 캐싱
cacheInputStream(request);
}
private void cacheInputStream(HttpServletRequest request) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
IOUtils.copy(request.getInputStream(), outputStream);
this.cachedBody = outputStream.toByteArray(); // 본문을 byte 배열에 저장
}
@Override
public ServletInputStream getInputStream() {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cachedBody); // 캐싱된 본문을 다시 읽기 위해 사용
return new ServletInputStream() {
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return byteArrayInputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
// No-op
}
};
}
}