
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package com.takensoft.common.oauth.handler;
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.common.oauth.vo.CustomOAuth2UserVO;
import com.takensoft.common.util.HttpRequestUtil;
import com.takensoft.common.util.JWTUtil;
import com.takensoft.common.util.SessionUtil;
import jakarta.servlet.ServletException;
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.context.ApplicationEventPublisher;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
/**
* @author takensoft
* @since 2025.05.22
* @modification
* since | author | description
* 2025.05.22 | takensoft | 최초 등록
*
* OAuth2 로그인 성공 핸들러
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private final LgnHstryService lgnHstryService;
private final HttpRequestUtil httpRequestUtil;
private final LoginModeService loginModeService;
private final LoginPolicyService loginPolicyService;
private final SessionUtil sessionUtil;
private final JWTUtil jwtUtil;
private final RedisTemplate<String, String> redisTemplate;
private final ApplicationEventPublisher eventPublisher;
@Value("${jwt.accessTime}")
private long JWT_ACCESSTIME;
@Value("${front.url}")
private String FRONT_URL;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
CustomOAuth2UserVO oAuth2User = (CustomOAuth2UserVO) authentication.getPrincipal();
try {
log.info("OAuth2 로그인 성공 - Provider: {}, Email: {}",
oAuth2User.getProvider(), oAuth2User.getEmail());
// 1. 비동기로 사용자 정보 저장/업데이트 처리
eventPublisher.publishEvent(new OAuth2UserSaveEvent(oAuth2User));
// 2. 로그인 이력 저장
saveLoginHistory(request, oAuth2User);
// 3. 로그인 모드에 따른 토큰/세션 처리
String loginMode = loginModeService.getLoginMode();
String tempUserId = createTempUserId(oAuth2User);
processLoginByMode(request, response, oAuth2User, tempUserId, loginMode);
// 4. 캐시 방지 헤더 설정
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
// 5. 프론트엔드 로그인 페이지로 리다이렉트 (OAuth 성공 파라미터 + 타임스탬프)
long timestamp = System.currentTimeMillis();
String redirectUrl = FRONT_URL + "/login.page?oauth_success=true&t=" + timestamp;
getRedirectStrategy().sendRedirect(request, response, redirectUrl);
} catch (Exception e) {
log.error("OAuth2 로그인 처리 중 오류 발생", e);
String errorUrl = FRONT_URL + "/login.page?error=oauth2_processing_failed";
getRedirectStrategy().sendRedirect(request, response, errorUrl);
}
}
/**
* 로그인 이력 저장
*/
private void saveLoginHistory(HttpServletRequest request, CustomOAuth2UserVO oAuth2User) {
try {
LgnHstryVO lgnHstryVO = new LgnHstryVO();
lgnHstryVO.setLgnId(oAuth2User.getEmail());
lgnHstryVO.setLgnType("1"); // 일반 사용자
lgnHstryVO.setCntnIp(httpRequestUtil.getIp(request));
lgnHstryVO.setCntnOperSys(httpRequestUtil.getOS(httpRequestUtil.getUserAgent(request)));
lgnHstryVO.setDeviceNm(httpRequestUtil.getDevice(httpRequestUtil.getUserAgent(request)));
lgnHstryVO.setBrwsrNm(httpRequestUtil.getBrowser(httpRequestUtil.getUserAgent(request)));
lgnHstryService.LgnHstrySave(lgnHstryVO);
} catch (Exception e) {
log.error("OAuth2 로그인 이력 저장 실패", e);
}
}
/**
* 임시 사용자 ID 생성
*/
private String createTempUserId(CustomOAuth2UserVO oAuth2User) {
return oAuth2User.getProvider() + "_" + oAuth2User.getId();
}
/**
* 로그인 모드에 따른 처리
*/
private void processLoginByMode(HttpServletRequest request, HttpServletResponse response,
CustomOAuth2UserVO oAuth2User, String tempUserId, String loginMode)
throws IOException {
// JWT 토큰 생성
String accessToken = jwtUtil.createJwt(
"Authorization",
tempUserId,
oAuth2User.getEmail(),
oAuth2User.getName(),
null, // roles는 DB 저장 후 갱신 예정
JWT_ACCESSTIME
);
if ("S".equals(loginMode)) {
// 세션 모드 처리
processSessionMode(request, tempUserId, accessToken, oAuth2User);
} else {
// JWT 모드 처리 (기본값)
processJwtMode(response, tempUserId, accessToken);
}
response.setHeader("login-type", loginMode);
}
/**
* 세션 모드 처리
*/
private void processSessionMode(HttpServletRequest request, String tempUserId,
String accessToken, CustomOAuth2UserVO oAuth2User) {
HttpSession session = request.getSession(true);
session.setAttribute("JWT_TOKEN", accessToken);
session.setAttribute("oauth2User", oAuth2User);
// 중복 로그인 정책 확인
if (!loginPolicyService.getPolicy()) {
sessionUtil.registerSession(tempUserId, session);
}
}
/**
* JWT 모드 처리
*/
private void processJwtMode(HttpServletResponse response, String tempUserId, String accessToken) {
response.setHeader("Authorization", accessToken);
// 중복 로그인 정책 확인
if (!loginPolicyService.getPolicy()) {
redisTemplate.delete("jwt:" + tempUserId);
redisTemplate.opsForValue().set("jwt:" + tempUserId, accessToken,
JWT_ACCESSTIME, TimeUnit.MILLISECONDS);
}
}
}