Request Body에 포함된 userId 값을 기반으로 로직을 처리하고 있다. 하지만 이 방식은 클라이언트가 임의로 다른 사용자의 userId를 입력해 악의적인 요청을 보낼 수 있다는 보안 문제가 있다. 따라서 API Gateway에서 JWT 토큰을 파싱해 생성한 X-User-Id 헤더 값을 활용하도록 코드를 수정해야 한다.board-service에서 코드 수정하기
public class CreateBoardRequestDto { private String title; private String content; private Long userId; public String getTitle() { return title; } public String getContent() { return content; } public Long getUserId() { return userId; } }
@RestController @RequestMapping("/api/boards") public class BoardController { ... @PostMapping public ResponseEntity<Void> create( @RequestBody CreateBoardRequestDto createBoardRequestDto, @RequestHeader("X-User-Id") Long userId ) { boardService.create(createBoardRequestDto, userId); return ResponseEntity.noContent().build(); } }
public void create(CreateBoardRequestDto createBoardRequestDto, Long userId) { // 게시글 저장을 성공했는 지 판단하는 플래그 boolean isBoardCreated = false; Long savedBoardId = null; // 포인트 차감을 성공했는 지 판단하는 플래그 boolean isPointDeducted = false; try { // 게시글 작성 전 100 포인트 차감 pointClient.deductPoints(userId, 100); isPointDeducted = true; // 포인트 차감 성공 플래그 System.out.println("포인트 차감 성공"); // 게시글 작성 Board board = new Board( createBoardRequestDto.getTitle(), createBoardRequestDto.getContent(), userId ); Board savedBoard = this.boardRepository.save(board); savedBoardId = savedBoard.getBoardId(); isBoardCreated = true; // 게시글 저장 성공 플래그 System.out.println("게시글 저장 성공"); // '게시글 작성 완료' 이벤트 발행 BoardCreatedEvent boardCreatedEvent = new BoardCreatedEvent(userId); this.kafkaTemplate.send("board.created", toJsonString(boardCreatedEvent)); } catch (Exception e) { if (isBoardCreated) { // 게시글 작성 보상 트랜잭션 => 게시글 삭제 this.boardRepository.deleteById(savedBoardId); System.out.println("[보상 트랜잭션] 게시글 삭제"); } if (isPointDeducted) { // 포인트 차감 보상 트랜잭션 => 포인트 적립 pointClient.addPoints(userId, 100); System.out.println("[보상 트랜잭션] 포인트 적립"); } // 실패 응답으로 처리하기 위해 예외 던지기 throw e; } }
