diff --git a/src/main/java/com/example/gtable/global/security/oauth2/OAuth2LoginSuccessHandler.java b/src/main/java/com/example/gtable/global/security/oauth2/OAuth2LoginSuccessHandler.java index 60ce2a6..fdbe236 100644 --- a/src/main/java/com/example/gtable/global/security/oauth2/OAuth2LoginSuccessHandler.java +++ b/src/main/java/com/example/gtable/global/security/oauth2/OAuth2LoginSuccessHandler.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.ServletException; +import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -28,7 +29,6 @@ // 1. JWT 토큰 발급 // - 이때, JWT payload는 보안상 최소한의 정보(userId, role)만 담겠다 // 2. refreshToken만 DB에 저장 -// 3. JSON 응답으로, accessToken과 refreshToken 을 반환해준다. @Component @RequiredArgsConstructor @Slf4j @@ -40,42 +40,32 @@ public class OAuth2LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHan public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException { - // 1. CustomOAuth2UserService에서 설정한 OAuth2User 정보 가져오기 - CustomOAuth2User customUserDetails = (CustomOAuth2User)authentication.getPrincipal(); - + CustomOAuth2User customUserDetails = (CustomOAuth2User) authentication.getPrincipal(); User user = customUserDetails.getUser(); Long userId = customUserDetails.getUserId(); - String email = customUserDetails.getName(); - - Collection authorities = authentication.getAuthorities(); - Iterator iterator = authorities.iterator(); - GrantedAuthority auth = iterator.next(); - - String role = auth.getAuthority(); + String role = authentication.getAuthorities().iterator().next().getAuthority(); - log.info("user, userId, email, role :: {} {} {} {}", user, userId, email, role); + // JWT 발급 + String accessToken = jwtUtil.createAccessToken("accessToken", userId, role, 30 * 60 * 1000L); // 30분 + String refreshToken = jwtUtil.createRefreshToken("refreshToken", userId, 30L * 24 * 60 * 60 * 1000L); // 30일 - // 2. 1)의 사용자 정보를 담아, accessToken과 refreshToken 발행 - String accessToken = jwtUtil.createAccessToken("accessToken", userId, role, 30 * 60 * 1000L); // 유효기간 30분 - String refreshToken = jwtUtil.createRefreshToken("refreshToken", userId, - 30 * 24 * 60 * 60 * 1000L); // 유효기간 30일 - - // 3. refreshToken을 DB에 저장 + // 1. refreshToken을 DB에 저장 Token refreshTokenEntity = Token.toEntity(user, refreshToken, LocalDateTime.now().plusDays(30)); tokenRepository.save(refreshTokenEntity); - // 4. JSON 응답으로, accessToken과 refreshToken 을 반환해준다. - response.setContentType("application/json"); - response.setCharacterEncoding("utf-8"); + // 2. refreshToken을 HttpOnly 쿠키로 설정 + Cookie refreshTokenCookie = new Cookie("refreshToken", refreshToken); + refreshTokenCookie.setHttpOnly(true); // JS 접근 불가 + refreshTokenCookie.setSecure(false); // 운영환경 https라면 true로 변경 필요 + refreshTokenCookie.setPath("/"); + refreshTokenCookie.setMaxAge(30 * 24 * 60 * 60); // 30일 + response.addCookie(refreshTokenCookie); + response.addHeader("Set-Cookie", response.getHeader("Set-Cookie") + "; SameSite=Lax"); + - ObjectMapper objectMapper = new ObjectMapper(); // 객체 -> json 문자열로 변환 - String body = objectMapper.writeValueAsString( - Map.of( - "accessToken", accessToken, - "refreshToken", refreshToken - ) - ); - response.getWriter().write(body); + // 3. 프론트엔드로 리다이렉트 (accessToken만 쿼리로 전달) + String targetUrl = "http://localhost:5173/login/success?accessToken=" + accessToken; + response.sendRedirect(targetUrl); } }