
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.cms.token.web;
import com.takensoft.cms.loginPolicy.service.LoginModeService;
import com.takensoft.cms.loginPolicy.service.LoginPolicyService;
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.ResponseData;
import com.takensoft.common.util.ResponseUtil;
import com.takensoft.common.util.SessionUtil;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.nio.charset.Charset;
/**
* @author takensoft
* @since 2024.04.01
* @modification
* since | author | description
* 2024.04.01 | takensoft | 최초 등록
* 2025.06.02 | takensoft | 세션 모드 Redis 정보 삭제 추가
*
* RefreshToken 정보 관련 컨트롤러
*/
@RestController
@RequiredArgsConstructor
@Slf4j
public class RefreshTokenController {
private final ResponseUtil resUtil;
private final RefreshTokenService refreshTokenService;
private final LoginPolicyService loginPolicyService;
private final LoginModeService loginModeService;
private final SessionUtil sessionUtil;
private final RedisTemplate<String, String> redisTemplate;
/**
* @param req - HTTP 요청 객체
* @param res - HTTP 응답 객체
* @return ResponseEntity - 로그아웃 응답 결과
*
* 로그아웃 - 세션/JWT 모드 통합 처리
*/
@PostMapping(value = "/mbr/logout.json")
public ResponseEntity<?> logout(HttpServletRequest req, HttpServletResponse res){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null && auth.getPrincipal() instanceof MberVO) {
MberVO mber = (MberVO) auth.getPrincipal();
String mbrId = mber.getMbrId();
String loginMode = loginModeService.getLoginMode(); // J or S
// Refresh 토큰 삭제 (DB)
RefreshTknVO refresh = new RefreshTknVO();
refresh.setMbrId(mbrId);
int result = refreshTokenService.delete(req, refresh);
if (loginMode.equals("S")) {
HttpSession session = req.getSession(false);
if (session != null) {
session.invalidate();
}
// SessionUtil에서 제거
sessionUtil.removeSession(mbrId);
// Redis에서 세션 정보 삭제 (중복로그인 관리용)
String sessionKey = "session:" + mbrId;
try {
redisTemplate.delete(sessionKey);
} catch (Exception e) {
}
// JSESSIONID 쿠키 제거
Cookie cookie = new Cookie("JSESSIONID", null);
cookie.setMaxAge(0); // 삭제
cookie.setPath("/");
res.addCookie(cookie);
} else {
// JWT 방식: Redis에서 삭제
if (!loginPolicyService.getPolicy()) {
try {
redisTemplate.delete("jwt:" + mbrId);
} catch (Exception e) {
}
}
// refresh 쿠키 제거
Cookie cookie = new Cookie("refresh", null);
cookie.setMaxAge(0);
cookie.setHttpOnly(true);
cookie.setPath("/");
res.addCookie(cookie);
}
// SecurityContext 제거
SecurityContextHolder.clearContext();
return resUtil.successRes(result, MessageCode.LOGOUT_SUCCESS);
}
return resUtil.errorRes(MessageCode.COMMON_UNKNOWN_ERROR);
}
/**
* @param req - HTTP 요청 객체
* @param res - HTTP 응답 객체
* @return ResponseEntity - 토큰 재발급 응답 결과
*
* 토큰 재발급
*/
@PostMapping("/refresh/tokenReissue.json")
public ResponseEntity<?> tokenReissue(HttpServletRequest req, HttpServletResponse res) {
int result = refreshTokenService.tokenReissueProc(req, res);
// 응답 처리
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
ResponseData responseData = new ResponseData();
if(result > 0) {
return resUtil.successRes(result, MessageCode.COMMON_SUCCESS);
} else {
responseData.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
responseData.setStatusText(HttpStatus.INTERNAL_SERVER_ERROR);
responseData.setMessage("로그인을 다시해주시기 바랍니다.");
return new ResponseEntity<>(responseData, headers, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}