Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ public RsData<Void> logout(HttpServletRequest request, HttpServletResponse respo

@Operation(summary = "현재 로그인한 유저 정보 조회", description = "세션 유효성 검증 및 사용자 정보 반환")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "인증된 유저 정보 반환 성공"),
@ApiResponse(responseCode = "401", description = "인증되지 않은 사용자"),
@ApiResponse(responseCode = "500", description = "서버 내부 오류")
@ApiResponse(responseCode = "200", description = "사용자 정보 조회"),
})
@GetMapping("/me")
public RsData<UserMeResDto> getCurrentUser() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,5 @@ public static class UserInfoDto {
private final String nickname;
private final Boolean isFirstLogin;
private final Double abvDegree;

}
}
40 changes: 33 additions & 7 deletions src/main/java/com/back/domain/user/service/UserAuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import java.util.Optional;
import java.util.Set;

import static org.springframework.security.core.context.SecurityContextHolder.*;

@Slf4j
@Service
@RequiredArgsConstructor
Expand Down Expand Up @@ -199,14 +201,30 @@ public RefreshTokenResDto refreshTokens(HttpServletRequest request, HttpServletR

//토큰 끊기면서 OAuth 자동 로그아웃
public void logout(HttpServletRequest request, HttpServletResponse response) {
// 1. RefreshToken DB에서 삭제
String refreshToken = jwtUtil.getRefreshTokenFromCookie(request);

if (refreshToken != null) {
refreshTokenService.revokeToken(refreshToken);
}

// 2. JWT 쿠키 삭제
jwtUtil.removeAccessTokenCookie(response);
jwtUtil.removeRefreshTokenCookie(response);

// 3. Spring Security 세션 무효화 (Redis 포함)
try {
if (request.getSession(false) != null) {
request.getSession().invalidate();
log.debug("세션 무효화");
}
} catch (IllegalStateException e) {
log.debug("세션이 이미 무효화되어 있음");
}

// 4. SecurityContext 클리어
clearContext();

log.info("로그아웃 완료 - JWT, 세션, SecurityContext 모두 정리됨");
}

@Transactional
Expand All @@ -216,21 +234,28 @@ public void setFirstLoginFalse(Long id) {
}

// 현재 로그인한 사용자 정보 조회 (세션 검증용)
// 변경: 항상 200 응답, 비로그인 시 user: null 반환
public UserMeResDto getCurrentUser() {
try {
User actor = rq.getActor();

// 비로그인 상태: user null 반환
if (actor == null) {
log.debug("인증되지 않은 사용자");
throw new ServiceException(401, "인증되지 않은 사용자");
log.debug("인증되지 않은 사용자 - user: null 반환");
return UserMeResDto.builder()
.user(null)
.build();
}

Optional<User> userOpt = userRepository.findById(actor.getId());
if (userOpt.isEmpty()) {
log.warn("사용자 ID {}를 DB에서 찾을 수 없음 (토큰은 유효하나 사용자 삭제됨)", actor.getId());
throw new ServiceException(401, "인증되지 않은 사용자");
return UserMeResDto.builder()
.user(null)
.build();
}

// 로그인 상태: user 정보 반환
User user = userOpt.get();
String provider = extractProvider(user.getOauthId());

Expand All @@ -245,11 +270,12 @@ public UserMeResDto getCurrentUser() {
.build())
.build();

} catch (ServiceException e) {
throw e;
} catch (Exception e) {
log.error("사용자 정보 조회 중 서버 오류 발생: {}", e.getMessage(), e);
throw new ServiceException(500, "서버 내부 오류");
// 예외 발생 시에도 user: null 반환
return UserMeResDto.builder()
.user(null)
.build();
}
}

Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/back/global/security/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.requestMatchers("/login/oauth2/**").permitAll()
.requestMatchers("/swagger-ui/**", "/api-docs/**").permitAll()
.requestMatchers("/user/auth/refresh").permitAll()
.requestMatchers("/user/auth/me").permitAll()
// 권한 불필요 - 조회 API
.requestMatchers(GET, "/cocktails/**").permitAll()
Expand Down
5 changes: 2 additions & 3 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,10 @@ custom:
jwt:
secretKey: ${JWT_SECRET_KEY}
accessToken:
expirationSeconds: "#{60}" # 15분 곱하기
expirationSeconds: "#{60*15}"
refreshToken:
expirationSeconds: "#{60*60*24*30}"
idleTimeoutHours: "#{1}"
# "#{60*6*4}"
idleTimeoutHours: "#{60*6*4}"


management:
Expand Down