이번 강의에서는 글 수정 API에서도 인증 정보를 전달하고,
단순히 “로그인했는지”를 넘어서 해당 글을 수정할 권한이 있는지(인가) 까지 검증하는 로직을 구현했다.
👉 이번 강의의 핵심은
“글 수정은 로그인만 했다고 되는 게 아니라, 작성자 본인인지 확인해야 한다”는 점이다.
@PutMapping("/{id}")
@Transactional
@Operation(summary = "수정")
public RsData<Void> modify(
@PathVariable int id,
@Valid @RequestBody PostModifyReqBody reqBody,
@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 입니다."));
Post post = postService.findById(id).get();
if (!actor.equals(post.getAuthor()))
throw new ServiceException("403-1", "글 수정 권한이 없습니다.");
postService.modify(post, reqBody.title, reqBody.content);
return new RsData<>(
"200-1",
"%d번 글이 수정되었습니다.".formatted(post.getId())
);
}
Authorization: Bearer {apiKey} 헤더를 전달👉 여기까지는 인증(Authentication) 단계
if (!actor.equals(post.getAuthor()))
throw new ServiceException("403-1", "글 수정 권한이 없습니다.");
이 부분이 인가(Authorization) 다.
이 질문이 자연스럽게 생길 수 있다.
“apiKey로 조회한 Member랑
post.getAuthor()로 가져온 Member는
서로 다른 객체 아닌가?”
@MappedSuperclass
@Getter
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = IDENTITY)
private int id;
@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);
}
}
즉,
actor.equals(post.getAuthor())
👉 BaseEntity의 equals 구현 덕분에 true
이 덕분에
actor.equals(post.getAuthor()) 비교는