이번 30강에서는 댓글 수정/삭제 요청에도 인증 정보(Authorization 헤더)를 전달하도록 맞추고, 그 인증된 사용자가 해당 댓글의 작성자인지(인가, 권한 체크)까지 검증하는 로직을 추가했다.
정리하면 흐름은 이거다.
@RequestHeader("Authorization") 로 헤더 값 받기 "Bearer " 제거해서 apiKey만 추출 memberService.findByApiKey(apiKey) 로 로그인한 사용자(actor) 찾기 actor.equals(postComment.getAuthor()) 로 작성자 일치 여부 확인403 에러로 막기컨트롤러에서 댓글 삭제는 이런 형태로 바뀌었다.
@NotBlank, @Size)핵심 로직은 아래다.
@NotBlank
@Size(min = 30, max = 50)
@RequestHeader("Authorization")
String authorization
String apiKey = authorization.replace("Bearer ", "");
Member actor = memberService.findByApiKey(apiKey)
.orElseThrow(() -> new ServiceException("401-1", "존재하지 않는 apiKey 입니다."));
PostComment postComment = post.findCommentById(id).get();
if (!actor.equals(postComment.getAuthor()))
throw new ServiceException("403-1", "댓글 삭제 권한이 없습니다.");
댓글 수정도 삭제와 완전히 같은 패턴이다.
핵심 로직만 보면 아래처럼 동일하다.
String apiKey = authorization.replace("Bearer ", "");
Member actor = memberService.findByApiKey(apiKey)
.orElseThrow(() -> new ServiceException("401-1", "존재하지 않는 apiKey 입니다."));
PostComment postComment = post.findCommentById(id).get();
if (!actor.equals(postComment.getAuthor()))
throw new ServiceException("403-1", "댓글 수정 권한이 없습니다.");
기존에 쿼리 파라미터로 apiKey 넘기던 방식이 아니라,
이제 테스트에서도 아래처럼 헤더를 붙여서 요청하도록 바뀌었다.
delete("/api/v1/posts/%d/comments/%d".formatted(postId, id))
.header("Authorization", "Bearer " + actorApiKey)
put("/api/v1/posts/%d/comments/%d".formatted(postId, id))
.header("Authorization", "Bearer " + actorApiKey)
.contentType(MediaType.APPLICATION_JSON)
.content(...)
나도 처음엔 “DB에서 각각 조회한 객체인데 어떻게 같다고 판단하지?”가 의문이었는데,
이 프로젝트는 BaseEntity에서 equals/hashCode를 id 기반으로 오버라이드 해두었기 때문에 가능했다.
현재 BaseEntity는 아래 기준으로 equals()가 동작한다.
getClass() 비교)@Override
public boolean equals(Object o) {
if (o == this) return true;
if (o == null || getClass() != o.getClass()) return false;
BaseEntity that = (BaseEntity) o;
return id == that.id;
}
@Override
public int hashCode() {
return Objects.hashCode(id);
}
즉,
그래서 아래 권한 체크가 정상적으로 성립한다.
if (!actor.equals(postComment.getAuthor()))
throw new ServiceException("403-1", "권한 없음");
댓글 수정/삭제 요청도 Authorization 헤더로 인증하고, 작성자(id) 기반 equals로 “본인 댓글만 수정/삭제 가능” 인가 체크를 추가했다.