하석형 하석형 05-26
250526 하석형 관리자로그인 2차인증
@481073ea0bbf7a63ade84016a1fbc908b206f9b7
src/main/java/com/takensoft/cms/mber/dto/LoginDTO.java
--- src/main/java/com/takensoft/cms/mber/dto/LoginDTO.java
+++ src/main/java/com/takensoft/cms/mber/dto/LoginDTO.java
@@ -26,4 +26,5 @@
     @NotNull
     private String pswd;            // 비밀번호
     private String refreshToken;    // refreshToken 정보
+    private String lgnReqPage;         // 로그인 요청 페이지 (관리자: A, 사용자: U)
 }
src/main/java/com/takensoft/common/config/SecurityConfig.java
--- src/main/java/com/takensoft/common/config/SecurityConfig.java
+++ src/main/java/com/takensoft/common/config/SecurityConfig.java
@@ -11,7 +11,9 @@
 import com.takensoft.common.exception.CustomAccessDenieHandler;
 import com.takensoft.common.exception.CustomAuthenticationEntryPoint;
 import com.takensoft.common.util.JWTUtil;
+import com.takensoft.common.util.LoginUtil;
 import com.takensoft.common.util.SessionUtil;
+import com.takensoft.common.verify.service.Impl.EmailServiceImpl;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -57,7 +59,9 @@
     private final AppConfig appConfig;
     private final LoginModeService loginModeService;
     private final LoginPolicyService loginPolicyService;
+    private final EmailServiceImpl emailServiceImpl;
     private final SessionUtil sessionUtil;
+    private final LoginUtil loginUtil;
 
     private static String FRONT_URL;    // 프론트 접근 허용 URL
     private static long JWT_ACCESSTIME; // access 토큰 유지 시간
@@ -80,7 +84,8 @@
      */
     public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, CntxtPthService cntxtPthService, AccesCtrlService accesCtrlService, AppConfig appConfig,
                           LgnHstryService lgnHstryService, CustomAuthenticationEntryPoint authenticationEntryPoint, CustomAccessDenieHandler accessDenieHandler, HttpRequestUtil httpRequestUtil,
-                          LoginModeService loginModeService, LoginPolicyService loginPolicyService, SessionUtil sessionUtil, @Value("${front.url}") String fUrl, @Value("${jwt.accessTime}") long aTime, @Value("${jwt.refreshTime}") long rTime, @Value("${cookie.time}") int ctime, RedisTemplate<String, String> redisTemplate) {
+                          LoginModeService loginModeService, LoginPolicyService loginPolicyService, EmailServiceImpl emailServiceImpl, SessionUtil sessionUtil, @Value("${front.url}") String fUrl, @Value("${jwt.accessTime}") long aTime, @Value("${jwt.refreshTime}") long rTime, @Value("${cookie.time}") int ctime, RedisTemplate<String, String> redisTemplate,
+                          LoginUtil loginUtil) {
 
         this.authenticationConfiguration = authenticationConfiguration;
         this.refreshTokenService = refreshTokenService;
@@ -94,12 +99,14 @@
         this.appConfig = appConfig;
         this.loginModeService = loginModeService;
         this.loginPolicyService = loginPolicyService;
+        this.emailServiceImpl = emailServiceImpl;
         this.sessionUtil = sessionUtil;
         this.FRONT_URL = fUrl;
         this.JWT_ACCESSTIME = aTime;
         this.JWT_REFRESHTIME = rTime;
         this.COOKIE_TIME = ctime;
         this.redisTemplate = redisTemplate;
+        this.loginUtil = loginUtil;
     }
 
     /**
@@ -180,7 +187,8 @@
 
         // 로그인 필터
         http.addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil, refreshTokenService, lgnHstryService, httpRequestUtil,
-                 loginModeService, loginPolicyService, sessionUtil, JWT_ACCESSTIME, JWT_REFRESHTIME, COOKIE_TIME, redisTemplate), UsernamePasswordAuthenticationFilter.class);
+                 loginModeService, loginPolicyService, emailServiceImpl, sessionUtil, JWT_ACCESSTIME, JWT_REFRESHTIME, COOKIE_TIME, redisTemplate,
+                loginUtil), UsernamePasswordAuthenticationFilter.class);
 
         return http.build();
     }
src/main/java/com/takensoft/common/filter/LoginFilter.java
--- src/main/java/com/takensoft/common/filter/LoginFilter.java
+++ src/main/java/com/takensoft/common/filter/LoginFilter.java
@@ -12,7 +12,10 @@
 import com.takensoft.common.exception.FilterExceptionHandler;
 import com.takensoft.common.util.HttpRequestUtil;
 import com.takensoft.common.util.JWTUtil;
+import com.takensoft.common.util.LoginUtil;
 import com.takensoft.common.util.SessionUtil;
+import com.takensoft.common.verify.service.Impl.EmailServiceImpl;
+import com.takensoft.common.verify.vo.EmailVO;
 import jakarta.servlet.http.HttpSession;
 import lombok.SneakyThrows;
 import org.springframework.beans.factory.annotation.Value;
@@ -55,7 +58,9 @@
     private final HttpRequestUtil httpRequestUtil;
     private final LoginModeService loginModeService;
     private final LoginPolicyService loginPolicyService;
+    private final EmailServiceImpl emailServiceImpl;
     private final SessionUtil sessionUtil;
+    private final LoginUtil loginUtil;
 
     private static long JWT_ACCESSTIME; // access 토큰 유지 시간
     private static long JWT_REFRESHTIME; // refresh 토큰 유지 시간
@@ -72,7 +77,8 @@
      * LoginFilter 생성자
      */
     public LoginFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil, RefreshTokenService refreshTokenService, LgnHstryService lgnHstryService, HttpRequestUtil httpRequestUtil,
-                       LoginModeService loginModeService,LoginPolicyService loginPolicyService,SessionUtil sessionUtil, @Value("${jwt.accessTime}")long aTime, @Value("${jwt.refreshTime}")long rTime, @Value("${cookie.time}")int ctime, RedisTemplate<String, String> redisTemplate) {
+                       LoginModeService loginModeService,LoginPolicyService loginPolicyService, EmailServiceImpl emailServiceImpl, SessionUtil sessionUtil, @Value("${jwt.accessTime}")long aTime, @Value("${jwt.refreshTime}")long rTime, @Value("${cookie.time}")int ctime, RedisTemplate<String, String> redisTemplate,
+                       LoginUtil loginUtil) {
         this.authenticationManager = authenticationManager;
         this.jwtUtil = jwtUtil;
         this.refreshTokenService = refreshTokenService;
@@ -80,12 +86,13 @@
         this.httpRequestUtil = httpRequestUtil;
         this.loginModeService = loginModeService;
         this.loginPolicyService = loginPolicyService;
+        this.emailServiceImpl = emailServiceImpl;
         this.sessionUtil = sessionUtil;
         this.JWT_ACCESSTIME = aTime;
         this.JWT_REFRESHTIME = rTime;
         this.COOKIE_TIME = ctime;
         this.redisTemplate = redisTemplate;
-
+        this.loginUtil = loginUtil;
 
         this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/mbr/loginProc.json","POST"));
     }
@@ -106,6 +113,7 @@
         // 클라이언트에서 요청한 아이디와 비밀번호 추출
         String lgnId = login.getLgnId();
         String pswd = login.getPswd();
+        req.setAttribute("lgnReqPage", login.getLgnReqPage());
 
         // 스프링 시큐리티에서 username과 password를 검증하기 위해서는 token에 담아야 함
         UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(lgnId, pswd, null);
@@ -127,71 +135,102 @@
     @SneakyThrows
     @Override
     protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication authentication) throws IOException {
+        Map<String, Object> result = new HashMap<>();
+
         MberVO mber = (MberVO) authentication.getPrincipal();
 
-        // 로그인 이력 등록
-        LgnHstryVO lgnHstryVO = new LgnHstryVO();
-        lgnHstryVO.setLgnId(mber.getLgnId());
-        if(mber.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_ADMIN"))) {
-            lgnHstryVO.setLgnType("0");
-        } else {
-            lgnHstryVO.setLgnType("1");
-        }
-        lgnHstryVO.setCntnIp(httpRequestUtil.getIp(req));
-        lgnHstryVO.setCntnOperSys(httpRequestUtil.getOS(httpRequestUtil.getUserAgent(req)));
-        lgnHstryVO.setDeviceNm(httpRequestUtil.getDevice(httpRequestUtil.getUserAgent(req)));
-        lgnHstryVO.setBrwsrNm(httpRequestUtil.getBrowser(httpRequestUtil.getUserAgent(req)));
-        lgnHstryService.LgnHstrySave(lgnHstryVO);
+        String lgnReqPage = (String) req.getAttribute("lgnReqPage");
+        // 로그인 요청 페이지가 관리자 페이지일 경우
+        if("A".equals(lgnReqPage)) {
+            // 관리자 권한이 있는지 확인
+            if(mber.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_ADMIN"))) {
+                EmailVO emailVO = new EmailVO().builder()
+                        .email(mber.getEml())
+                        .build();
+                emailServiceImpl.sendEmailVerifyCode(emailVO);
+                res.setContentType("application/json;charset=UTF-8");
+                res.setStatus(HttpStatus.OK.value());
+                result.put("mbrId", mber.getMbrId());
+                result.put("email", mber.getEml());
 
-        // 로그인 방식 확인 JWT or SESSION
-        String loginType = loginModeService.getLoginMode();
+                res.setContentType("application/json;charset=UTF-8");
+                res.setStatus(HttpStatus.OK.value());
 
-        // 토큰 생성(access, refresh)
-        String accessToken = jwtUtil.createJwt("Authorization", mber.getMbrId(), mber.getLgnId(), mber.getMbrNm(), (List) mber.getAuthorities(), JWT_ACCESSTIME);
-        String refreshToken = jwtUtil.createJwt("refresh", mber.getMbrId(), mber.getLgnId(), mber.getMbrNm(), (List) mber.getAuthorities(), JWT_REFRESHTIME);
+                new ObjectMapper().writeValue(res.getOutputStream(), result);
+            } else {
+                // 관리자 권한이 없는 경우 접근 권한이 없습니다
+                res.setContentType("application/json;charset=UTF-8");
+                res.setStatus(HttpStatus.FORBIDDEN.value());
 
-        // refreshToken이 현재 IP와 계정으로 등록되어 있는지 확인
-        RefreshTknVO refresh = new RefreshTknVO();
-        refresh.setMbrId(mber.getMbrId());
-
-        // refresh 토큰이 현재 아이피와 아이디로 DB에 등록 되어 있다면
-        if(refreshTokenService.findByCheckRefresh(req, refresh)) {
-            refreshTokenService.delete(req, refresh);
-        }
-        // refreshToken DB 저장
-        refresh.setToken(refreshToken);
-
-
-        if (loginType.equals("S")) {
-            HttpSession session = req.getSession(true);
-            session.setAttribute("JWT_TOKEN", accessToken);
-
-            // 중복 로그인 비허용일 때 기존 세션 만료
-            if (!loginPolicyService.getPolicy()) {
-                sessionUtil.registerSession(mber.getMbrId(), session);
+                result.put("message", "접근 권한이 없습니다.");
+                new ObjectMapper().writeValue(res.getOutputStream(), result);
             }
-            Map<String, Object> result = new HashMap<>();
-            result.put("mbrId", mber.getMbrId());
-            result.put("mbrNm", mber.getMbrNm());
-            result.put("roles", mber.getAuthorList());
-
-            res.setContentType("application/json;charset=UTF-8");
-            res.setStatus(HttpStatus.OK.value());
-
-            ObjectMapper mapper = new ObjectMapper();
-            res.getOutputStream().write(mapper.writeValueAsBytes(result));
         } else {
-            res.setHeader("Authorization", accessToken);
-            res.addCookie(jwtUtil.createCookie("refresh", refreshToken, COOKIE_TIME));
-
-            // 중복 로그인 비허용일 때 Redis 저장
-            if (!loginPolicyService.getPolicy()) {
-                redisTemplate.delete("jwt:" + mber.getMbrId());
-                redisTemplate.opsForValue().set("jwt:" + mber.getMbrId(), accessToken, JWT_ACCESSTIME, TimeUnit.MILLISECONDS);
-            }
+            loginUtil.successLogin(mber, req, res);
+//            // 로그인 이력 등록
+//            LgnHstryVO lgnHstryVO = new LgnHstryVO();
+//            lgnHstryVO.setLgnId(mber.getLgnId());
+//            if (mber.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_ADMIN"))) {
+//                lgnHstryVO.setLgnType("0");
+//            } else {
+//                lgnHstryVO.setLgnType("1");
+//            }
+//            lgnHstryVO.setCntnIp(httpRequestUtil.getIp(req));
+//            lgnHstryVO.setCntnOperSys(httpRequestUtil.getOS(httpRequestUtil.getUserAgent(req)));
+//            lgnHstryVO.setDeviceNm(httpRequestUtil.getDevice(httpRequestUtil.getUserAgent(req)));
+//            lgnHstryVO.setBrwsrNm(httpRequestUtil.getBrowser(httpRequestUtil.getUserAgent(req)));
+//            lgnHstryService.LgnHstrySave(lgnHstryVO);
+//
+//            // 로그인 방식 확인 JWT or SESSION
+//            String loginType = loginModeService.getLoginMode();
+//
+//            // 토큰 생성(access, refresh)
+//            String accessToken = jwtUtil.createJwt("Authorization", mber.getMbrId(), mber.getLgnId(), mber.getMbrNm(), (List) mber.getAuthorities(), JWT_ACCESSTIME);
+//            String refreshToken = jwtUtil.createJwt("refresh", mber.getMbrId(), mber.getLgnId(), mber.getMbrNm(), (List) mber.getAuthorities(), JWT_REFRESHTIME);
+//
+//            // refreshToken이 현재 IP와 계정으로 등록되어 있는지 확인
+//            RefreshTknVO refresh = new RefreshTknVO();
+//            refresh.setMbrId(mber.getMbrId());
+//
+//            // refresh 토큰이 현재 아이피와 아이디로 DB에 등록 되어 있다면
+//            if (refreshTokenService.findByCheckRefresh(req, refresh)) {
+//                refreshTokenService.delete(req, refresh);
+//            }
+//            // refreshToken DB 저장
+//            refresh.setToken(refreshToken);
+//
+//
+//            if (loginType.equals("S")) {
+//                HttpSession session = req.getSession(true);
+//                session.setAttribute("JWT_TOKEN", accessToken);
+//
+//                // 중복 로그인 비허용일 때 기존 세션 만료
+//                if (!loginPolicyService.getPolicy()) {
+//                    sessionUtil.registerSession(mber.getMbrId(), session);
+//                }
+//                Map<String, Object> result = new HashMap<>();
+//                result.put("mbrId", mber.getMbrId());
+//                result.put("mbrNm", mber.getMbrNm());
+//                result.put("roles", mber.getAuthorList());
+//
+//                res.setContentType("application/json;charset=UTF-8");
+//                res.setStatus(HttpStatus.OK.value());
+//
+//                ObjectMapper mapper = new ObjectMapper();
+//                res.getOutputStream().write(mapper.writeValueAsBytes(result));
+//            } else {
+//                res.setHeader("Authorization", accessToken);
+//                res.addCookie(jwtUtil.createCookie("refresh", refreshToken, COOKIE_TIME));
+//
+//                // 중복 로그인 비허용일 때 Redis 저장
+//                if (!loginPolicyService.getPolicy()) {
+//                    redisTemplate.delete("jwt:" + mber.getMbrId());
+//                    redisTemplate.opsForValue().set("jwt:" + mber.getMbrId(), accessToken, JWT_ACCESSTIME, TimeUnit.MILLISECONDS);
+//                }
+//            }
+//            refreshTokenService.saveRefreshToken(req, res, refresh, JWT_REFRESHTIME);
+//            res.setHeader("login-type", loginType);
         }
-        refreshTokenService.saveRefreshToken(req, res, refresh, JWT_REFRESHTIME);
-        res.setHeader("login-type", loginType);
     }
 
     /**
src/main/java/com/takensoft/common/message/MessageCode.java
--- src/main/java/com/takensoft/common/message/MessageCode.java
+++ src/main/java/com/takensoft/common/message/MessageCode.java
@@ -69,6 +69,7 @@
     FILE_UPLOAD_FAIL("file.upload_fail", HttpStatus.INTERNAL_SERVER_ERROR), // 파일 업로드 실패
 
     // 이메일 인증 관련
+    EMAIL_SEND_SUCCESS("email.send_success", HttpStatus.OK), // 이메일 발송 성공
     EMAIL_SEND_FAIL("email.send_fail", HttpStatus.INTERNAL_SERVER_ERROR), // 이메일 발송 실패
     EMAIL_VERIFY_SUCCESS("email.verify_success", HttpStatus.OK), // 이메일 인증 성공
     EMAIL_VERIFY_EXPIRED("email.verify_expired", HttpStatus.UNAUTHORIZED), // 이메일 인증 만료
 
src/main/java/com/takensoft/common/util/LoginUtil.java (added)
+++ src/main/java/com/takensoft/common/util/LoginUtil.java
@@ -0,0 +1,112 @@
+package com.takensoft.common.util;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.cms.loginPolicy.service.LoginModeService;
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
+import com.takensoft.cms.mber.service.LgnHstryService;
+import com.takensoft.cms.mber.vo.LgnHstryVO;
+import com.takensoft.cms.mber.vo.MberVO;
+import com.takensoft.cms.token.service.RefreshTokenService;
+import com.takensoft.cms.token.vo.RefreshTknVO;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+@Component
+@RequiredArgsConstructor
+public class LoginUtil {
+    private final LgnHstryService lgnHstryService;
+    private final HttpRequestUtil httpRequestUtil;
+    private final LoginModeService loginModeService;
+    private final RefreshTokenService refreshTokenService;
+    private final LoginPolicyService loginPolicyService;
+    private final JWTUtil jwtUtil;
+    private final SessionUtil sessionUtil;
+    private final RedisTemplate<String, String> redisTemplate;
+
+    @Value("${jwt.accessTime}")
+    private long JWT_ACCESSTIME;
+    @Value("${jwt.refreshTime}")
+    private long JWT_REFRESHTIME;
+    @Value("${cookie.time}")
+    private int COOKIE_TIME;
+
+    public void successLogin(MberVO mber, HttpServletRequest req, HttpServletResponse res) {
+        try {
+            // 로그인 이력 등록
+            LgnHstryVO lgnHstryVO = new LgnHstryVO();
+            lgnHstryVO.setLgnId(mber.getLgnId());
+            lgnHstryVO.setLgnType(mber.getAuthorities().stream().anyMatch(role -> role.getAuthority().equals("ROLE_ADMIN")) ? "0" : "1");
+            lgnHstryVO.setCntnIp(httpRequestUtil.getIp(req));
+            lgnHstryVO.setCntnOperSys(httpRequestUtil.getOS(httpRequestUtil.getUserAgent(req)));
+            lgnHstryVO.setDeviceNm(httpRequestUtil.getDevice(httpRequestUtil.getUserAgent(req)));
+            lgnHstryVO.setBrwsrNm(httpRequestUtil.getBrowser(httpRequestUtil.getUserAgent(req)));
+            lgnHstryService.LgnHstrySave(lgnHstryVO);
+
+            // 로그인 방식 확인 JWT or SESSION
+            String loginType = loginModeService.getLoginMode();
+
+            // 토큰 생성(access, refresh)
+            String accessToken = jwtUtil.createJwt("Authorization", mber.getMbrId(), mber.getLgnId(), mber.getMbrNm(), (List) mber.getAuthorities(), JWT_ACCESSTIME);
+            String refreshToken = jwtUtil.createJwt("refresh", mber.getMbrId(), mber.getLgnId(), mber.getMbrNm(), (List) mber.getAuthorities(), JWT_REFRESHTIME);
+
+            // refreshToken이 현재 IP와 계정으로 등록되어 있는지 확인
+            RefreshTknVO refresh = new RefreshTknVO();
+            refresh.setMbrId(mber.getMbrId());
+
+            // refresh 토큰이 현재 아이피와 아이디로 DB에 등록 되어 있다면
+            if (refreshTokenService.findByCheckRefresh(req, refresh)) {
+                refreshTokenService.delete(req, refresh);
+            }
+            // refreshToken DB 저장
+            refresh.setToken(refreshToken);
+
+            if ("S".equals(loginType)) {
+                HttpSession session = req.getSession(true);
+                session.setAttribute("JWT_TOKEN", accessToken);
+
+                // 중복 로그인 비허용일 때 기존 세션 만료
+                if (!loginPolicyService.getPolicy()) {
+                    sessionUtil.registerSession(mber.getMbrId(), session);
+                }
+                Map<String, Object> result = new HashMap<>();
+                result.put("mbrId", mber.getMbrId());
+                result.put("mbrNm", mber.getMbrNm());
+                result.put("roles", mber.getAuthorList());
+
+                res.setContentType("application/json;charset=UTF-8");
+                res.setStatus(HttpStatus.OK.value());
+                new ObjectMapper().writeValue(res.getOutputStream(), result);
+            } else {
+                res.setHeader("Authorization", accessToken);
+                res.addCookie(jwtUtil.createCookie("refresh", refreshToken, COOKIE_TIME));
+
+                // 중복 로그인 비허용일 때 Redis 저장
+                if (!loginPolicyService.getPolicy()) {
+                    redisTemplate.delete("jwt:" + mber.getMbrId());
+                    redisTemplate.opsForValue().set("jwt:" + mber.getMbrId(), accessToken, JWT_ACCESSTIME, TimeUnit.MILLISECONDS);
+                }
+            }
+
+            refreshTokenService.saveRefreshToken(req, res, refresh, JWT_REFRESHTIME);
+            res.setHeader("login-type", loginType);
+        }
+        catch (IOException ioe) {
+            throw new RuntimeException(ioe);
+        }
+        catch (Exception e) {
+            throw e;
+        }
+    }
+}
src/main/java/com/takensoft/common/verify/service/Impl/EmailServiceImpl.java
--- src/main/java/com/takensoft/common/verify/service/Impl/EmailServiceImpl.java
+++ src/main/java/com/takensoft/common/verify/service/Impl/EmailServiceImpl.java
@@ -41,8 +41,6 @@
     private final EmailDAO emailDAO;
     private final JWTUtil jwtUtil;
     private final JavaMailSender mailSender;
-//    @Autowired
-//    @Qualifier("redisTemplateObject")
     private final RedisTemplate<String, Object> redisTemplate;
 
     @Value("${spring.mail.verifyTime}")
src/main/java/com/takensoft/common/verify/vo/EmailVO.java
--- src/main/java/com/takensoft/common/verify/vo/EmailVO.java
+++ src/main/java/com/takensoft/common/verify/vo/EmailVO.java
@@ -15,9 +15,12 @@
  */
 @Setter
 @Getter
+@ToString
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class EmailVO {
+    private String mbrId;       // 회원아이디
     private String email;       // 이메일
     private String code;        // 인증코드
     private long createdAt;     // 인증코드 생성일시
src/main/java/com/takensoft/common/verify/web/EmailController.java
--- src/main/java/com/takensoft/common/verify/web/EmailController.java
+++ src/main/java/com/takensoft/common/verify/web/EmailController.java
@@ -1,22 +1,39 @@
 package com.takensoft.common.verify.web;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.takensoft.cms.loginPolicy.service.LoginModeService;
+import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
+import com.takensoft.cms.mber.service.LgnHstryService;
+import com.takensoft.cms.mber.service.MberService;
+import com.takensoft.cms.mber.vo.LgnHstryVO;
+import com.takensoft.cms.mber.vo.MberVO;
+import com.takensoft.cms.token.service.RefreshTokenService;
+import com.takensoft.cms.token.vo.RefreshTknVO;
 import com.takensoft.common.message.MessageCode;
-import com.takensoft.common.util.ResponseUtil;
+import com.takensoft.common.util.*;
 import com.takensoft.common.verify.service.EmailService;
 import com.takensoft.common.verify.vo.EmailVO;
+import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.OutputStream;
 import java.net.URLEncoder;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @author 하석형
@@ -35,6 +52,23 @@
 
     private final EmailService emailService;
     private final ResponseUtil resUtil;
+    private final MberService mberService;
+    private final HttpRequestUtil httpRequestUtil;
+    private final LgnHstryService lgnHstryService;
+    private final LoginModeService loginModeService;
+    private final RefreshTokenService refreshTokenService;
+    private final LoginPolicyService loginPolicyService;
+    private final JWTUtil jwtUtil;
+    private final SessionUtil sessionUtil;
+    private final RedisTemplate<String, String> redisTemplate;
+    private final LoginUtil loginUtil;
+
+    @Value("${jwt.accessTime}")
+    private long JWT_ACCESSTIME;
+    @Value("${jwt.refreshTime}")
+    private long JWT_REFRESHTIME;
+    @Value("${cookie.time}")
+    private int COOKIE_TIME; // 쿠키 유지 시간
 
     /**
      * @param emailVO - 이메일 정보
@@ -47,7 +81,7 @@
 
         boolean result = emailService.sendEmailVerifyCode(emailVO);
 
-        return resUtil.successRes(result, MessageCode.COMMON_SUCCESS);
+        return resUtil.successRes(result, MessageCode.EMAIL_SEND_SUCCESS);
     }
 
     /**
@@ -63,4 +97,33 @@
 
         return resUtil.successRes(result, MessageCode.COMMON_SUCCESS);
     }
+
+    /**
+     * @param emailVO - 이메일 정보
+     * @return ResponseEntity - 이메일 인증코드 확인 응답 결과
+     *
+     * 2차 인증 이메일 인증코드 확인
+     */
+    @PostMapping("/check2ndAuthEmailVerifyCode.json")
+    public void check2ndAuthEmailVerifyCode(@RequestBody EmailVO emailVO, HttpServletRequest req, HttpServletResponse res) throws IOException {
+
+        boolean authResult = emailService.checkEmailVerifyCode(emailVO); // 이메일 인증코드 확인
+        if(authResult) {
+            HashMap<String, Object> findMber = new HashMap<>();
+            findMber.put("mbrId", emailVO.getMbrId());
+            MberVO mber = mberService.findByMbr(findMber);
+
+            loginUtil.successLogin(mber, req, res);
+        } else {
+            // 인증 실패 시 예외 처리
+            Map<String, Object> result = new HashMap<>();
+            res.setContentType("application/json;charset=UTF-8");
+            res.setStatus(HttpStatus.UNAUTHORIZED.value());
+            result.put("message", "인증에 실패했습니다. 올바른 인증코드를 입력해주세요.");
+            new ObjectMapper().writeValue(res.getOutputStream(), result);
+            return;
+        }
+
+//        return resUtil.successRes(authResult, MessageCode.COMMON_SUCCESS);
+    }
 }
src/main/resources/message/messages_en.yml
--- src/main/resources/message/messages_en.yml
+++ src/main/resources/message/messages_en.yml
@@ -61,6 +61,7 @@
 
 # 이메일 인증 관련
 email:
+  send_success: "Email sent successfully."
   send_fail: "Failed to send email."
   verify_success: "Email verification completed successfully."
   verify_expired: "Email verification has expired."
src/main/resources/message/messages_ko.yml
--- src/main/resources/message/messages_ko.yml
+++ src/main/resources/message/messages_ko.yml
@@ -62,6 +62,7 @@
 
 # 이메일 인증 관련
 email:
+  send_success: "이메일을 발송했습니다."
   send_fail: "이메일 발송에 실패했습니다."
   verify_success: "이메일 인증이 완료되었습니다."
   verify_expired: "인증 시간이 만료되었습니다."
Add a comment
List