jwt와 시큐리티를 이용한 게시판 REST API를 만들면서 생긴 오류입니다.

스웨거를 이용하여 로그인을 후 JWT 토큰을 받습니다.

User 1 : Board N 으로 매핑을 하였습니다. 그러나 user: null이 나왔고,
데이터베이스를 확인

user_id가 null이 뜨는 문제점을 발견하였고, 이에 대해서 고민을 해보았습니다.
그러나 생각해보니 매핑만 하고 Service로직을 바꾸지 않은 치명적인 실수였습니다.ㅜㅜ
package com.springboot.jwt_securityprac2.service.Impl;
import com.springboot.jwt_securityprac2.dto.BoardDTO.BoardRequestDto;
import com.springboot.jwt_securityprac2.dto.BoardDTO.BoardResponseDto;
import com.springboot.jwt_securityprac2.entity.Board;
import com.springboot.jwt_securityprac2.entity.User;
import com.springboot.jwt_securityprac2.jwt.JwtProvider;
import com.springboot.jwt_securityprac2.repository.BoardRepository;
import com.springboot.jwt_securityprac2.repository.UserRepository;
import com.springboot.jwt_securityprac2.service.BoardService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
@Service
public class BoardServiceImpl implements BoardService {
private Logger logger = LoggerFactory.getLogger(BoardService.class);
private final BoardRepository boardRepository;
private final UserRepository userRepository;
private JwtProvider jwtProvider;
public BoardServiceImpl(BoardRepository boardRepository,JwtProvider jwtProvider
,UserRepository userRepository){
this.boardRepository = boardRepository;
this.jwtProvider = jwtProvider;
this.userRepository = userRepository;
}
@Override
public BoardResponseDto getContent(Long id){
logger.info("[getContent] : 게시글 반환");
Board board = boardRepository.findById(id).get();
BoardResponseDto boardResponseDto = new BoardResponseDto();
boardResponseDto.setId(board.getId());
boardResponseDto.setContent(board.getContent());
boardResponseDto.setTitle(board.getTitle());
boardResponseDto.setUpdateAt(board.getCreateDate());
boardResponseDto.setUpdateAt(board.getUpdateDate());
return boardResponseDto;
}
@Override
public BoardResponseDto saveBoard(BoardRequestDto boardRequestDto) {
logger.info("[saveBoard] 게시글 저장 : {}",boardRequestDto.toString());
Board board = new Board();
board.setTitle(boardRequestDto.getTitle());
board.setContent(boardRequestDto.getContent());
board.setCreateDate(LocalDateTime.now());
board.setUpdateDate(LocalDateTime.now());
Board savedBoard = boardRepository.save(board);
BoardResponseDto boardResponseDto = new BoardResponseDto();
boardResponseDto.setId(savedBoard.getId());
boardResponseDto.setTitle(savedBoard.getTitle());
boardResponseDto.setContent(savedBoard.getContent());
boardResponseDto.setCreateAt(LocalDateTime.now());
boardResponseDto.setUpdateAt(LocalDateTime.now());
boardResponseDto.setUser(savedBoard.getUser());
return boardResponseDto;
}
@Override
public BoardResponseDto changeBoard(Long id, String title, String content){
logger.info("[changeBoard] : 게시글 수정");
Board findBoard = boardRepository.getById(id);
findBoard.setTitle(title);
findBoard.setContent(content);
findBoard.setUpdateDate(LocalDateTime.now());
Board board = boardRepository.save(findBoard);
BoardResponseDto boardResponseDto = new BoardResponseDto();
boardResponseDto.setId(board.getId());
boardResponseDto.setTitle(board.getTitle());
boardResponseDto.setContent(board.getContent());
boardResponseDto.setUpdateAt(LocalDateTime.now());
return boardResponseDto;
}
@Override
public void deleteBoard(Long id){
logger.info("[deleteBoard] : 게시글 삭제");
boardRepository.deleteById(id);
}
}
saveBoard()메서드를 보면 알 수 있듯이, 검증된 유저를 받아서 저장하는 로직이 비어있어서 추가 하였습니다!
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-> 현재 실행 중인 스레드의 보안 컨텍스트에서 Authentication 객체를 가져옵니다. Authentication 객체는 현재 인증된 사용자의 정보를 포함하고 있습니다. 이 객체에는 사용자의 이름, 권한, 기타 세부 정보 등이 포함될 수 있습니다.
String email = authentication.getName();
-> 여기서 authentication.getName() 메서드는 일반적으로 현재 인증된 사용자의 사용자명을 반환합니다. 스프링 시큐리티에서 사용자명은 일반적으로 사용자의 주요 식별자로 사용됩니다.
User user = userRepository.getByEmail(email);
userRepository.getByEmail(email);
-> 이 메서드는 데이터베이스에서 주어진 이메일 주소를 가진 User 엔티티를 검색합니다. 이 메서드는 userRepository 인터페이스에 정의된 메서드일 것이며, 이메일을 기반으로 사용자를 찾기 위한 쿼리를 실행합니다. 이렇게 검색된 User 객체는 게시판 엔티티에 사용자 정보를 연결하는 데 사용될 수 있습니다.
@Override
public BoardResponseDto saveBoard(BoardRequestDto boardRequestDto) {
logger.info("[saveBoard] 게시글 저장 : {}",boardRequestDto.toString());
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); //추가한코드
String email = authentication.getName(); //추가한코드
User user = userRepository.getByEmail(email); //추가한코드
Board board = new Board();
board.setTitle(boardRequestDto.getTitle());
board.setContent(boardRequestDto.getContent());
board.setCreateDate(LocalDateTime.now());
board.setUpdateDate(LocalDateTime.now());
board.setUser(user); //추가한코드
Board savedBoard = boardRepository.save(board);
BoardResponseDto boardResponseDto = new BoardResponseDto();
boardResponseDto.setId(savedBoard.getId());
boardResponseDto.setTitle(savedBoard.getTitle());
boardResponseDto.setContent(savedBoard.getContent());
boardResponseDto.setCreateAt(LocalDateTime.now());
boardResponseDto.setUpdateAt(LocalDateTime.now());
boardResponseDto.setUser(savedBoard.getUser());
return boardResponseDto;
}
데이터베이스를 확인해 보겠습니다!!!
로직을 추가하니 매핑을 하여 잘들어옵니다!!