diff --git a/src/main/java/com/readyvery/readyverydemo/security/config/SpringSecurityConfig.java b/src/main/java/com/readyvery/readyverydemo/security/config/SpringSecurityConfig.java index a605338..15685d9 100644 --- a/src/main/java/com/readyvery/readyverydemo/security/config/SpringSecurityConfig.java +++ b/src/main/java/com/readyvery/readyverydemo/security/config/SpringSecurityConfig.java @@ -28,9 +28,9 @@ import com.readyvery.readyverydemo.security.customlogin.handler.LoginSuccessHandler; import com.readyvery.readyverydemo.security.customlogin.service.CustomLoginCeoService; import com.readyvery.readyverydemo.security.exception.CustomAuthenticationEntryPoint; +import com.readyvery.readyverydemo.security.jwt.config.JwtConfig; import com.readyvery.readyverydemo.security.jwt.filter.JwtAuthenticationProcessingFilter; import com.readyvery.readyverydemo.security.jwt.service.JwtService; -import com.readyvery.readyverydemo.security.jwt.service.JwtTokenizer; import com.readyvery.readyverydemo.security.oauth2.handler.OAuth2LoginFailureHandler; import com.readyvery.readyverydemo.security.oauth2.handler.OAuth2LoginSuccessHandler; import com.readyvery.readyverydemo.security.oauth2.service.CustomOAuth2UserService; @@ -45,7 +45,7 @@ public class SpringSecurityConfig { private final JwtService jwtService; private final CeoRepository ceoRepository; private final ObjectMapper objectMapper; - private final JwtTokenizer jwtTokenizer; + private final JwtConfig jwtConfig; private final CustomLoginCeoService customLoginCeoService; private final OAuth2LoginSuccessHandler oAuth2LoginSuccessHandler; private final OAuth2LoginFailureHandler oAuth2LoginFailureHandler; @@ -119,7 +119,7 @@ public PasswordEncoder passwordEncoder() { @Bean public LoginSuccessHandler loginSuccessHandler() { - return new LoginSuccessHandler(jwtService, ceoRepository, jwtTokenizer, objectMapper); + return new LoginSuccessHandler(jwtService, ceoRepository); } @Bean diff --git a/src/main/java/com/readyvery/readyverydemo/security/customlogin/handler/LoginSuccessHandler.java b/src/main/java/com/readyvery/readyverydemo/security/customlogin/handler/LoginSuccessHandler.java index 0ea0f60..72dddcc 100644 --- a/src/main/java/com/readyvery/readyverydemo/security/customlogin/handler/LoginSuccessHandler.java +++ b/src/main/java/com/readyvery/readyverydemo/security/customlogin/handler/LoginSuccessHandler.java @@ -1,16 +1,11 @@ package com.readyvery.readyverydemo.security.customlogin.handler; -import java.io.IOException; - import org.springframework.security.core.Authentication; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler; -import com.fasterxml.jackson.databind.ObjectMapper; import com.readyvery.readyverydemo.domain.repository.CeoRepository; import com.readyvery.readyverydemo.security.jwt.service.JwtService; -import com.readyvery.readyverydemo.security.jwt.service.JwtTokenizer; -import com.readyvery.readyverydemo.src.ceo.dto.CeoLoginRes; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -23,8 +18,6 @@ public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { private final JwtService jwtService; private final CeoRepository ceoRepository; - private final JwtTokenizer jwtTokenizer; - private final ObjectMapper objectMapper; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, @@ -41,24 +34,6 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo ceoRepository.saveAndFlush(ceoInfo); }); - // JSON 응답 생성 및 전송 - - response.setContentType("application/json;charset=UTF-8"); - response.setStatus(HttpServletResponse.SC_OK); - CeoLoginRes ceoLoginRes = CeoLoginRes.builder() - .success(true) - .message("로그인 성공") - .build(); - - try { - String jsonResponse = objectMapper.writeValueAsString(ceoLoginRes); - response.getWriter().write(jsonResponse); - } catch (IOException e) { - log.error("응답 작성 중 에러 발생", e); - } - log.info("로그인에 성공하였습니다. 이메일 : {}", email); - log.info("로그인에 성공하였습니다. AccessToken : {}", accessToken); - log.info("발급된 AccessToken 만료 기간 : {}", jwtTokenizer.getAccessTokenExpirationPeriod()); } private String extractCeoname(Authentication authentication) { diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/config/JwtConfig.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/config/JwtConfig.java index 445fb0e..8b26069 100644 --- a/src/main/java/com/readyvery/readyverydemo/security/jwt/config/JwtConfig.java +++ b/src/main/java/com/readyvery/readyverydemo/security/jwt/config/JwtConfig.java @@ -25,6 +25,7 @@ public class JwtConfig { public static final String REFRESH_TOKEN_SUBJECT = "RefreshToken"; public static final String EMAIL_CLAIM = "email"; public static final String USER_NUMBER = "userNumber"; + public static final String BEARER = "Bearer "; @Value("${jwt.secretKey}") public void setSecretKey(String secretKey) { diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/filter/JwtAuthenticationProcessingFilter.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/filter/JwtAuthenticationProcessingFilter.java index 6f1d253..cca3ea2 100644 --- a/src/main/java/com/readyvery/readyverydemo/security/jwt/filter/JwtAuthenticationProcessingFilter.java +++ b/src/main/java/com/readyvery/readyverydemo/security/jwt/filter/JwtAuthenticationProcessingFilter.java @@ -46,7 +46,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse // -> RefreshToken이 없거나 유효하지 않다면(DB에 저장된 RefreshToken과 다르다면) null을 반환 // 사용자의 요청 헤더에 RefreshToken이 있는 경우는, AccessToken이 만료되어 요청한 경우밖에 없다. // 따라서, 위의 경우를 제외하면 추출한 refreshToken은 모두 null - String refreshToken = jwtService.extractRefreshTokenFromCookies(request) + String refreshToken = jwtService.extractRefreshToken(request) .filter(jwtService::isTokenValid) .orElse(null); @@ -106,7 +106,7 @@ private String reIssueRefreshToken(CeoInfo ceoInfo) { public void checkAccessTokenAndAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - jwtService.extractAccessTokenFromCookies(request) + jwtService.extractAccessToken(request) .filter(jwtService::isTokenValid) .ifPresent(accessToken -> jwtService.extractEmail(accessToken) .ifPresent(email -> ceoRepository.findByEmail(email) diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtService.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtService.java index 572c377..0e47817 100644 --- a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtService.java +++ b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtService.java @@ -26,12 +26,12 @@ public interface JwtService { /** * 쿠키에서 RefreshToken 추출 */ - Optional extractRefreshTokenFromCookies(HttpServletRequest request); + Optional extractRefreshToken(HttpServletRequest request); /** * 쿠키에서 AccessToken 추출 */ - Optional extractAccessTokenFromCookies(HttpServletRequest request); + Optional extractAccessToken(HttpServletRequest request); /** * AccessToken에서 Email 추출 diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtServiceImpl.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtServiceImpl.java index 2996286..3a62083 100644 --- a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtServiceImpl.java +++ b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtServiceImpl.java @@ -1,7 +1,5 @@ package com.readyvery.readyverydemo.security.jwt.service; -import java.util.Arrays; -import java.util.NoSuchElementException; import java.util.Optional; import org.springframework.stereotype.Service; @@ -9,8 +7,13 @@ import com.auth0.jwt.JWT; import com.readyvery.readyverydemo.domain.CeoInfo; import com.readyvery.readyverydemo.domain.repository.CeoRepository; +import com.readyvery.readyverydemo.global.exception.BusinessLogicException; +import com.readyvery.readyverydemo.global.exception.ExceptionCode; +import com.readyvery.readyverydemo.security.jwt.config.JwtConfig; +import com.readyvery.readyverydemo.security.jwt.service.create.JwtTokenGenerator; +import com.readyvery.readyverydemo.security.jwt.service.extract.ExtractToken; +import com.readyvery.readyverydemo.security.jwt.service.sendmanger.JwtTokenizer; -import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.Getter; @@ -25,15 +28,17 @@ public class JwtServiceImpl implements JwtService { private final CeoRepository ceoRepository; private final JwtTokenizer jwtTokenizer; + private final JwtTokenGenerator jwtTokenGenerator; + private final JwtConfig jwtConfig; + private final ExtractToken extractToken; /** * AccessToken 생성 메소드 */ @Override public String createAccessToken(String email) { - CeoInfo ceoInfo = ceoRepository.findByEmail(email) - .orElseThrow(() -> new IllegalArgumentException("이메일에 해당하는 유저가 없습니다.")); - return jwtTokenizer.generateAccessToken(email, ceoInfo.getId()); + CeoInfo ceoInfo = getCeoInfo(email); + return jwtTokenGenerator.generateAccessToken(email, ceoInfo.getId()); } /** @@ -43,7 +48,7 @@ public String createAccessToken(String email) { @Override public String createRefreshToken() { - return jwtTokenizer.generateRefreshToken(); + return jwtTokenGenerator.generateRefreshToken(); } /** @@ -52,41 +57,26 @@ public String createRefreshToken() { @Override public void sendAccessAndRefreshToken(HttpServletResponse response, String accessToken, String refreshToken) { - response.setStatus(HttpServletResponse.SC_OK); - - jwtTokenizer.setAccessTokenCookie(response, accessToken); - jwtTokenizer.setRefreshTokenCookie(response, refreshToken); + jwtTokenizer.addAccessRefreshTokenResponseBody(response, accessToken, refreshToken); + jwtTokenizer.addAccessTokenCookie(response, accessToken); + jwtTokenizer.addRefreshTokenCookie(response, refreshToken); log.info("Access Token, Refresh Token 헤더 설정 완료"); } /** - * 쿠키에서 RefreshToken 추출 + * RefreshToken 추출 */ @Override - public Optional extractRefreshTokenFromCookies(HttpServletRequest request) { - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - return Arrays.stream(cookies) - .filter(cookie -> jwtTokenizer.getRefreshCookie().equals(cookie.getName())) // 올바른 필터링 조건 - .findFirst() - .map(Cookie::getValue); - } - return Optional.empty(); + public Optional extractRefreshToken(HttpServletRequest request) { + return extractToken.extractTokenCookie(request, jwtConfig.getRefreshTokenName()); } /** - * 쿠키에서 AccessToken 추출 + * AccessToken 추출 */ @Override - public Optional extractAccessTokenFromCookies(HttpServletRequest request) { - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - return Arrays.stream(cookies) - .filter(cookie -> jwtTokenizer.getAccessCookie().equals(cookie.getName())) // 올바른 필터링 조건 - .findFirst() - .map(Cookie::getValue); - } - return Optional.empty(); + public Optional extractAccessToken(HttpServletRequest request) { + return extractToken.extractTokenHeader(request, jwtConfig.getAccessTokenName()); } /** @@ -113,9 +103,7 @@ public Optional extractEmail(String accessToken) { @Override public void updateRefreshToken(String email, String refreshToken) { - CeoInfo ceoInfo = ceoRepository.findByEmail(email) - .orElseThrow(() -> new NoSuchElementException("일치하는 회원이 없습니다.")); - + CeoInfo ceoInfo = getCeoInfo(email); ceoInfo.updateRefresh(refreshToken); ceoRepository.save(ceoInfo); } @@ -123,7 +111,7 @@ public void updateRefreshToken(String email, String refreshToken) { @Override public boolean isTokenValid(String token) { try { - JWT.require(jwtTokenizer.getAlgorithm()).build().verify(token); + JWT.require(jwtConfig.getAlgorithm()).build().verify(token); return true; } catch (Exception e) { log.error("유효하지 않은 토큰입니다. {}", e.getMessage()); @@ -131,4 +119,10 @@ public boolean isTokenValid(String token) { } } + private CeoInfo getCeoInfo(String email) { + return ceoRepository.findByEmail(email).orElseThrow( + () -> new BusinessLogicException(ExceptionCode.USER_NOT_FOUND) + ); + } + } diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtTokenizer.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtTokenizer.java deleted file mode 100644 index d14a8e8..0000000 --- a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/JwtTokenizer.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.readyvery.readyverydemo.security.jwt.service; - -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.Date; -import java.util.Optional; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import com.auth0.jwt.JWT; -import com.auth0.jwt.algorithms.Algorithm; - -import jakarta.servlet.http.Cookie; -import jakarta.servlet.http.HttpServletResponse; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Component -@Slf4j -@Getter -public class JwtTokenizer { - - public static final String ACCESS_TOKEN_SUBJECT = "AccessToken"; - public static final String REFRESH_TOKEN_SUBJECT = "RefreshToken"; - public static final String EMAIL_CLAIM = "email"; - public static final String USER_NUMBER = "userNumber"; - - private String secretKey; - private Long accessTokenExpirationPeriod; - private Long refreshTokenExpirationPeriod; - private Algorithm algorithm; - - private String accessCookie; - private String refreshCookie; - private String frontendUrl; - private String cookieDomain; - - @Value("${jwt.secretKey}") - public void setSecretKey(String secretKey) { - this.secretKey = secretKey; - initializeAlgorithm(); - } - - @Value("${jwt.access.expiration}") - public void setAccessTokenExpirationPeriod(Long accessTokenExpirationPeriod) { - this.accessTokenExpirationPeriod = accessTokenExpirationPeriod; - } - - @Value("${jwt.refresh.expiration}") - public void setRefreshTokenExpirationPeriod(Long refreshTokenExpirationPeriod) { - this.refreshTokenExpirationPeriod = refreshTokenExpirationPeriod; - } - - @Value("${jwt.access.cookie}") - public void setAccessCookie(String accessCookie) { - this.accessCookie = accessCookie; - } - - @Value("${jwt.refresh.cookie}") - public void setRefreshCookie(String refreshCookie) { - this.refreshCookie = refreshCookie; - } - - @Value("${jwt.redirect-uri}") - public void setFrontendUrl(String frontendUrl) { - this.frontendUrl = frontendUrl; - } - - @Value("${jwt.refresh.cookie.domain}") - public void setCookieDomain(String cookieDomain) { - this.cookieDomain = cookieDomain; - } - - public String generateAccessToken(String email, Long ceoId) { - Instant now = Instant.now(); - Instant expirationTime = now.plus(accessTokenExpirationPeriod, ChronoUnit.SECONDS); - return JWT.create() - .withSubject(ACCESS_TOKEN_SUBJECT) - .withExpiresAt(Date.from(expirationTime)) - .withClaim(EMAIL_CLAIM, email) - .withClaim(USER_NUMBER, ceoId) - .sign(algorithm); - } - - public String generateRefreshToken() { - Instant now = Instant.now(); - Instant expirationTime = now.plus(refreshTokenExpirationPeriod, ChronoUnit.SECONDS); - return JWT.create() - .withSubject(REFRESH_TOKEN_SUBJECT) - .withExpiresAt(Date.from(expirationTime)) - .sign(algorithm); - } - - public void setAccessTokenCookie(HttpServletResponse response, String accessToken) { - Cookie accessTokenCookie = new Cookie(accessCookie, accessToken); - accessTokenCookie.setPath("/"); - accessTokenCookie.setDomain(cookieDomain); - accessTokenCookie.setMaxAge(accessTokenExpirationPeriod.intValue()); - response.addCookie(accessTokenCookie); - } - - public void setRefreshTokenCookie(HttpServletResponse response, String refreshToken) { - Cookie refreshTokenCookie = new Cookie(refreshCookie, refreshToken); - refreshTokenCookie.setHttpOnly(true); - refreshTokenCookie.setPath("/api/v1/refresh/token"); - refreshTokenCookie.setDomain(cookieDomain); - refreshTokenCookie.setMaxAge(refreshTokenExpirationPeriod.intValue()); - response.addCookie(refreshTokenCookie); - } - - public Optional verifyAccessToken(String accessToken) { - return Optional.ofNullable(JWT.require(algorithm) - .build() - .verify(accessToken) - .getClaim(EMAIL_CLAIM) - .asString()); - } - - private void initializeAlgorithm() { - if (secretKey != null && !secretKey.isEmpty()) { - algorithm = Algorithm.HMAC512(secretKey); - } - } -} diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/create/HmacJwtTokenGenerator.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/create/HmacJwtTokenGenerator.java new file mode 100644 index 0000000..6e3dffe --- /dev/null +++ b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/create/HmacJwtTokenGenerator.java @@ -0,0 +1,45 @@ +package com.readyvery.readyverydemo.security.jwt.service.create; + +import static com.readyvery.readyverydemo.security.jwt.config.JwtConfig.*; + +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Date; + +import org.springframework.stereotype.Component; + +import com.auth0.jwt.JWT; +import com.readyvery.readyverydemo.security.jwt.config.JwtConfig; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +public class HmacJwtTokenGenerator implements JwtTokenGenerator { + + private final JwtConfig jwtConfig; + + @Override + public String generateAccessToken(String email, Long ceoId) { + // 토큰 생성 로직 + Instant now = Instant.now(); + Instant expirationTime = now.plus(jwtConfig.getAccessTokenExpirationPeriod(), ChronoUnit.SECONDS); + return JWT.create() + .withSubject(ACCESS_TOKEN_SUBJECT) + .withExpiresAt(Date.from(expirationTime)) + .withClaim(EMAIL_CLAIM, email) + .withClaim(USER_NUMBER, ceoId) + .sign(jwtConfig.getAlgorithm()); + } + + @Override + public String generateRefreshToken() { + // 토큰 생성 로직 + Instant now = Instant.now(); + Instant expirationTime = now.plus(jwtConfig.getRefreshTokenExpirationPeriod(), ChronoUnit.SECONDS); + return JWT.create() + .withSubject(REFRESH_TOKEN_SUBJECT) + .withExpiresAt(Date.from(expirationTime)) + .sign(jwtConfig.getAlgorithm()); + } +} diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/create/JwtTokenGenerator.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/create/JwtTokenGenerator.java new file mode 100644 index 0000000..4410204 --- /dev/null +++ b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/create/JwtTokenGenerator.java @@ -0,0 +1,7 @@ +package com.readyvery.readyverydemo.security.jwt.service.create; + +public interface JwtTokenGenerator { + String generateAccessToken(String email, Long ceoId); + + String generateRefreshToken(); +} diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/extract/ExtractToken.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/extract/ExtractToken.java new file mode 100644 index 0000000..747ed96 --- /dev/null +++ b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/extract/ExtractToken.java @@ -0,0 +1,33 @@ +package com.readyvery.readyverydemo.security.jwt.service.extract; + +import static com.readyvery.readyverydemo.security.jwt.config.JwtConfig.*; + +import java.util.Arrays; +import java.util.Optional; + +import org.springframework.stereotype.Component; + +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; + +@Component +public class ExtractToken { + + public Optional extractTokenCookie(HttpServletRequest request, String tokenName) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + return Arrays.stream(cookies) + .filter(cookie -> tokenName.equals(cookie.getName())) + .findFirst() + .map(Cookie::getValue); + } + return Optional.empty(); + } + + public Optional extractTokenHeader(HttpServletRequest request, String tokenName) { + return Optional.ofNullable(request.getHeader(tokenName)) + .filter(refreshToken -> refreshToken.startsWith(BEARER)) + .map(refreshToken -> refreshToken.replace(BEARER, "")); + } + +} diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/sendmanger/JwtTokenizer.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/sendmanger/JwtTokenizer.java new file mode 100644 index 0000000..fbe5de5 --- /dev/null +++ b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/sendmanger/JwtTokenizer.java @@ -0,0 +1,55 @@ +package com.readyvery.readyverydemo.security.jwt.service.sendmanger; + +import static com.readyvery.readyverydemo.security.jwt.config.JwtConfig.*; + +import java.util.Optional; + +import org.springframework.context.annotation.Configuration; + +import com.auth0.jwt.JWT; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.readyvery.readyverydemo.security.jwt.config.JwtConfig; +import com.readyvery.readyverydemo.security.jwt.service.create.JwtTokenGenerator; + +import jakarta.servlet.http.HttpServletResponse; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Configuration +@Slf4j +@Getter +@RequiredArgsConstructor +public class JwtTokenizer { + + private final JwtTokenGenerator tokenGenerator; + private final TokenSendManager tokenSendManager; + private final ObjectMapper objectMapper; + private final JwtConfig jwtConfig; + + public void addAccessTokenCookie(HttpServletResponse response, String accessToken) { + tokenSendManager.addTokenCookie(response, jwtConfig.getAccessTokenName(), accessToken, "/", + jwtConfig.getAccessTokenExpirationPeriod().intValue(), false); + } + + public void addRefreshTokenCookie(HttpServletResponse response, String refreshToken) { + tokenSendManager.addTokenCookie(response, jwtConfig.getRefreshTokenName(), refreshToken, + "/api/v1/refresh/token", + jwtConfig.getRefreshTokenExpirationPeriod().intValue(), true); + } + + public void addAccessRefreshTokenResponseBody(HttpServletResponse response, String accessToken, + String refreshToken) { + tokenSendManager.addTokenResponseBody(response, accessToken, refreshToken); + + } + + public Optional verifyAccessToken(String accessToken) { + return Optional.ofNullable(JWT.require(jwtConfig.getAlgorithm()) + .build() + .verify(accessToken) + .getClaim(EMAIL_CLAIM) + .asString()); + } + +} diff --git a/src/main/java/com/readyvery/readyverydemo/security/jwt/service/sendmanger/TokenSendManager.java b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/sendmanger/TokenSendManager.java new file mode 100644 index 0000000..5d63f3c --- /dev/null +++ b/src/main/java/com/readyvery/readyverydemo/security/jwt/service/sendmanger/TokenSendManager.java @@ -0,0 +1,55 @@ +package com.readyvery.readyverydemo.security.jwt.service.sendmanger; + +import java.io.IOException; + +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.readyvery.readyverydemo.security.jwt.config.JwtConfig; +import com.readyvery.readyverydemo.src.ceo.dto.CeoLoginRes; + +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@RequiredArgsConstructor +@Component +@Slf4j +public class TokenSendManager { + private final JwtConfig jwtConfig; + private final ObjectMapper objectMapper; + + public void addTokenCookie(HttpServletResponse response, String name, String value, String path, int maxAge, + boolean httpOnly) { + Cookie cookie = new Cookie(name, value); + cookie.setHttpOnly(httpOnly); + cookie.setPath(path); + cookie.setDomain(jwtConfig.getCookieDomain()); + cookie.setMaxAge(maxAge); + response.addCookie(cookie); + + } + + public void addTokenResponseBody(HttpServletResponse response, String accessToken, String refreshToken) { + + // JSON 응답 생성 및 전송 + + response.setContentType("application/json;charset=UTF-8"); + response.setStatus(HttpServletResponse.SC_OK); + CeoLoginRes ceoLoginRes = CeoLoginRes.builder() + .success(true) + .message("로그인 성공") + .accessToken(accessToken) + .refreshToken(refreshToken) + .build(); + + try { + String jsonResponse = objectMapper.writeValueAsString(ceoLoginRes); + response.getWriter().write(jsonResponse); + } catch (IOException e) { + log.error("응답 작성 중 에러 발생", e); + } + } + +} diff --git a/src/main/java/com/readyvery/readyverydemo/src/ceo/dto/CeoLoginRes.java b/src/main/java/com/readyvery/readyverydemo/src/ceo/dto/CeoLoginRes.java index 265c87d..1cbf52e 100644 --- a/src/main/java/com/readyvery/readyverydemo/src/ceo/dto/CeoLoginRes.java +++ b/src/main/java/com/readyvery/readyverydemo/src/ceo/dto/CeoLoginRes.java @@ -8,4 +8,6 @@ public class CeoLoginRes { private boolean success; private String message; + private String accessToken; + private String refreshToken; }