글을 수정하거나 삭제할 때 요청 헤더에 토큰을 전달하므로 사용자 자신이 작성한 글인지 검증할 수 있다. 따라서 본인 글이 아닌 글을 수정, 삭제를 시도하는 경우, 예외를 발생시킬 수 있도록 코드를 수정한다.
수정 및 삭제 메서드는 실행 전에 현재 사용자와 글의 작성자를 비교하는 authorizeArticleAuthor() 메서드를 호출한 후 두 사용자가 다르면 예외를 발생시켜 작업을 중단하는 로직을 추가한다.
// service - BlogService.java
@RequiredArgsConstructor
@Service
public class BlogService {
private final BlogRepository blogRepository;
~ 생략 ~
public void delete(long id) {
Article article = blogRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("not found : " + id));
authorizeArticleAuthor(article);
blogRepository.delete(article);
}
@Transactional
public Article update(long id, UpdateArticleRequest request) {
Article article = blogRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("not found : " + id));
authorizeArticleAuthor(article);
article.update(request.getTitle(), request.getContent());
return article;
}
// 게시글을 작성한 유저인지 확인
private static void authorizeArticleAuthor(Article article) {
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
if (!article.getAuthor().equals(userName)) {
throw new IllegalArgumentException("not authorized");
}
}
}
SecurityContextHolder.getContext().getAuthentication().getName();
SecurityContextHolder
보안 주체의 세부정보를 포함하여 응용프로그램의 현재 보안 컨텍스트에 대한 세부 정보가 저장된다.
getContext()
현재 스레드의 보안 컨텍스트를 반환한다. 이를 통해 현재 사용자의 인증 및 권한 정보에 접근할 수 있다.
getAuthentication()
현재 사용자의 인증 객체를 가져온다. 해당 객체는 사용자의 자격 증명 및 권한을 나타내는 데 사용된다.
getName()
인증된 사용자의 이름을 반환한다. 이것은 주로 사용자의 로그인 이름이나 고유 식별자일 수 있다.