Skip to content

Commit 56fe1f3

Browse files
authored
[fix] 댓글 수정/삭제 500 오류 해결 #222 (#224)
* Revert "chore: initData용 이미지 추가" This reverts commit ef30eef. * . * fix: 댓글 수정/삭제 시 작성자 비교 로직 개선 댓글 수정 및 삭제 로직에서 현재 로그인한 사용자와 댓글 작성자를 비교할 때, 기존에 객체(`comment.getUser().equals(user)`)를 비교하던 방식에서 ID 값(`comment.getUser().getId().equals(user.getId())`)을 비교하는 방식으로 변경 * fix: JWT 인증 토큰 획득 로직 개선 (Header 우선 적용)
1 parent 8a67f5f commit 56fe1f3

File tree

2 files changed

+90
-57
lines changed

2 files changed

+90
-57
lines changed

src/main/java/com/back/domain/post/comment/service/CommentService.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public CommentResponseDto updateComment(Long postId, Long commentId, CommentUpda
9595

9696
Comment comment = findCommentWithValidation(postId, commentId);
9797

98-
if (!comment.getUser().equals(user)) {
98+
if (!comment.getUser().getId().equals(user.getId())) {
9999
throw new IllegalStateException("본인의 댓글만 수정할 수 있습니다.");
100100
}
101101

@@ -113,7 +113,7 @@ public void deleteComment(Long postId, Long commentId) {
113113

114114
Comment comment = findCommentWithValidation(postId, commentId);
115115

116-
if (!comment.getUser().equals(user)) {
116+
if (!comment.getUser().getId().equals(user.getId())) {
117117
throw new IllegalStateException("본인의 댓글만 삭제할 수 있습니다.");
118118
}
119119

src/main/java/com/back/global/security/CustomAuthenticationFilter.java

Lines changed: 88 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -55,87 +55,120 @@ private void work(HttpServletRequest request, HttpServletResponse response, Filt
5555
String uri = request.getRequestURI();
5656
String method = request.getMethod();
5757

58-
// 개발 편의성을 위해 모든 요청 통과 (SecurityConfig에서 모든 요청 permitAll)
59-
/*
60-
if (
61-
uri.startsWith("/h2-console") ||
62-
uri.startsWith("/login/oauth2/") ||
63-
uri.startsWith("/oauth2/") ||
64-
uri.startsWith("/actuator/") ||
65-
uri.startsWith("/swagger-ui/") ||
66-
uri.startsWith("/api-docs/") ||
67-
uri.equals("/") ||
68-
// 조회 API들 - 권한 불필요
69-
(method.equals("GET") && uri.startsWith("/cocktails")) ||
70-
(method.equals("POST") && uri.equals("/cocktails/search")) ||
71-
(method.equals("GET") && uri.startsWith("/posts")) ||
72-
(method.equals("GET") && uri.contains("/comments"))
73-
) {
74-
filterChain.doFilter(request, response);
75-
return;
76-
}
77-
*/
58+
log.debug("===== Authentication Filter Start =====");
59+
log.debug("Request: {} {}", method, uri);
7860

79-
// 쿠키에서 accessToken 가져오기
80-
String accessToken = rq.getCookieValue("accessToken", "");
61+
String accessToken = null;
62+
63+
// 1. 먼저 Authorization 헤더에서 토큰 가져오기 시도
64+
String authHeader = request.getHeader("Authorization");
65+
if (authHeader != null && authHeader.startsWith("Bearer ")) {
66+
accessToken = authHeader.substring(7);
67+
log.debug("Token found in Authorization header");
68+
}
8169

82-
logger.debug("accessToken : " + accessToken);
70+
// 2. Authorization 헤더에 없으면 쿠키에서 가져오기
71+
if (accessToken == null || accessToken.isBlank()) {
72+
accessToken = rq.getCookieValue("accessToken", "");
73+
if (!accessToken.isBlank()) {
74+
log.debug("Token found in Cookie");
75+
}
76+
}
8377

8478
boolean isAccessTokenExists = !accessToken.isBlank();
8579

8680
if (!isAccessTokenExists) {
81+
log.debug("No access token found - proceeding without authentication");
8782
filterChain.doFilter(request, response);
8883
return;
8984
}
9085

9186
User user = null;
92-
boolean isAccessTokenValid = false;
9387

9488
// accessToken 검증
95-
if (isAccessTokenExists) {
96-
if (jwtUtil.validateAccessToken(accessToken)) {
89+
if (jwtUtil.validateAccessToken(accessToken)) {
90+
log.debug("Access token is valid");
91+
92+
try {
9793
Long userId = jwtUtil.getUserIdFromToken(accessToken);
9894
String email = jwtUtil.getEmailFromToken(accessToken);
9995
String nickname = jwtUtil.getNicknameFromToken(accessToken);
10096

101-
user = User.builder()
102-
.id(userId)
103-
.email(email)
104-
.nickname(nickname)
105-
.role("USER")
106-
.build();
107-
isAccessTokenValid = true;
97+
if (userId != null) {
98+
user = User.builder()
99+
.id(userId)
100+
.email(email)
101+
.nickname(nickname)
102+
.role("USER")
103+
.build();
104+
105+
log.debug("User extracted - ID: {}, Email: {}, Nickname: {}", userId, email, nickname);
106+
} else {
107+
log.warn("User ID is null in token");
108+
}
109+
} catch (Exception e) {
110+
log.error("Error extracting user info from token", e);
111+
}
112+
} else {
113+
log.warn("Access token validation failed");
114+
115+
// 토큰이 만료된 경우에도 정보 추출 시도 (선택적)
116+
try {
117+
Long userId = jwtUtil.getUserIdFromToken(accessToken);
118+
String email = jwtUtil.getEmailFromToken(accessToken);
119+
String nickname = jwtUtil.getNicknameFromToken(accessToken);
120+
121+
if (userId != null && email != null && nickname != null) {
122+
user = User.builder()
123+
.id(userId)
124+
.email(email)
125+
.nickname(nickname)
126+
.role("USER")
127+
.build();
128+
129+
// 새 토큰 발급 (쿠키 방식을 사용하는 경우만)
130+
if (authHeader == null) {
131+
String newAccessToken = jwtUtil.generateAccessToken(userId, email, nickname);
132+
rq.setCrossDomainCookie("accessToken", newAccessToken, accessTokenExpiration);
133+
log.info("New access token issued for user: {}", userId);
134+
}
135+
}
136+
} catch (Exception e) {
137+
log.error("Failed to extract user info from expired token", e);
108138
}
109139
}
110140

141+
// user가 null이면 인증 실패
111142
if (user == null) {
143+
log.warn("Authentication failed - user is null");
112144
filterChain.doFilter(request, response);
113145
return;
114146
}
115147

116-
// accessToken이 만료됐으면 새로 발급
117-
if (isAccessTokenExists && !isAccessTokenValid) {
118-
String newAccessToken = jwtUtil.generateAccessToken(user.getId(), user.getEmail(), user.getNickname());
119-
rq.setCrossDomainCookie("accessToken", newAccessToken, accessTokenExpiration);
120-
}
121-
122148
// SecurityContext에 인증 정보 저장
123-
UserDetails userDetails = new SecurityUser(
124-
user.getId(),
125-
user.getEmail(),
126-
user.getNickname(),
127-
user.isFirstLogin(),
128-
user.getAuthorities(),
129-
Map.of() // JWT 인증에서는 빈 attributes
130-
);
131-
Authentication authentication = new UsernamePasswordAuthenticationToken(
132-
userDetails,
133-
userDetails.getPassword(),
134-
userDetails.getAuthorities()
135-
);
136-
SecurityContextHolder
137-
.getContext()
138-
.setAuthentication(authentication);
149+
try {
150+
UserDetails userDetails = new SecurityUser(
151+
user.getId(),
152+
user.getEmail(),
153+
user.getNickname(),
154+
user.isFirstLogin(),
155+
user.getAuthorities(),
156+
Map.of() // JWT 인증에서는 빈 attributes
157+
);
158+
159+
Authentication authentication = new UsernamePasswordAuthenticationToken(
160+
userDetails,
161+
userDetails.getPassword(),
162+
userDetails.getAuthorities()
163+
);
164+
165+
SecurityContextHolder.getContext().setAuthentication(authentication);
166+
167+
log.info("✅ Authentication SUCCESS - User ID: {}, Nickname: {}", user.getId(), user.getNickname());
168+
log.debug("===== Authentication Filter End =====");
169+
} catch (Exception e) {
170+
log.error("Error setting authentication in SecurityContext", e);
171+
}
139172

140173
filterChain.doFilter(request, response);
141174
}

0 commit comments

Comments
 (0)