본문 바로가기
❤️‍🔥TIL (Today I Learned)

[TIL] 2023-01-03(47day)

by elicho91 2023. 1. 3.

3차 프로젝트 Spring Security


👉 Post Controller / Security 적용 전

RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class PostController {
    private final PostService postService;
    private final JwtUtil jwtUtil;

    @PostMapping("/posts")
    public PostResponseDto createPost(@RequestBody PostRequestDto requestDto, HttpServletRequest request) {
        //Request에서 Token 가져오기
        String token = jwtUtil.resolveToken(request);
        // 토큰 유효성 검증, 토큰에서 사용자 정보 가져오기
        if (token != null) {
            AuthenticatedUser authenticatedUser = jwtUtil.validateTokenAndGetInfo(token);
            return postService.createPost(requestDto, authenticatedUser.getUsername());
        } else {
            throw new IllegalArgumentException("토큰이 존재하지 않습니다.");
        }
    }

    @GetMapping("/posts")
    public List<PostResponseDto> getAllBlogs() {
        return postService.getAllBlogs();
    }

    @GetMapping("/posts/{postId}")
    public PostResponseDto getPost(@PathVariable Long postId) {
        return postService.getPosts(postId);
    }

    @PutMapping("/posts/{postId}")
    public PostResponseDto updatePost(@PathVariable Long postId, @RequestBody PostRequestDto requestDto, HttpServletRequest request) {
        String token = jwtUtil.resolveToken(request);
        if (token != null) {
            AuthenticatedUser authenticatedUser = jwtUtil.validateTokenAndGetInfo(token);
            return postService.updatePost(postId, requestDto, authenticatedUser.getUsername());
        } else {
            throw new IllegalArgumentException("토큰이 존재하지 않습니다.");
        }
    }

    @DeleteMapping("/posts{postId}")
    public ResponseEntity<String> deletePost(@PathVariable Long postId, HttpServletRequest request) {

        String token = jwtUtil.resolveToken(request);

        if (token != null) {
            AuthenticatedUser authenticatedUser = jwtUtil.validateTokenAndGetInfo(token);
            return postService.deletePost(postId, authenticatedUser.getUsername());
        } else {
            return new ResponseEntity<>("토큰이 존재하지 않습니다.", HttpStatus.BAD_REQUEST);
        }
    }

    @PostMapping("/posts/{postId}")
    public ResponseEntity<String> likeOrDislikePost(@PathVariable Long postId, HttpServletRequest request) {
        String token = jwtUtil.resolveToken(request);
        if (token != null) {
            AuthenticatedUser authenticatedUser = jwtUtil.validateTokenAndGetInfo(token);
            return postService.likeOrDislikePost(postId, authenticatedUser.getUsername());
        } else {
            throw new IllegalArgumentException("토큰이 존재하지 않습니다.");
        }
    }

}

 

👉 Post Controller / Security 적용 후

@RestController
@RequiredArgsConstructor
@RequestMapping("/api")
public class PostController {
    private final PostService postService;
    private final JwtUtil jwtUtil;

    @PostMapping("/posts")
    public PostResponseDto createPost(@RequestBody PostRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return postService.createPost(requestDto, userDetails.getUser());
    }

    @GetMapping("/posts")
    public List<PostResponseDto> getAllPost() {
        return postService.getAllPost();
    }

    @GetMapping("/posts/{id}")
    public PostResponseDto getPost(@PathVariable Long id) {
        return postService.getPosts(id);
    }

    @PutMapping("/posts/{id}")
    public PostResponseDto updatePost(@PathVariable Long id, @RequestBody PostRequestDto requestDto, @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return postService.updatePost(id, requestDto, userDetails.getUser());
    }

    @DeleteMapping("/posts/{id}")
    public ResponseEntity<String> deletePost(@PathVariable Long id, @AuthenticationPrincipal UserDetailsImpl userDetails) {
        return postService.deletePost(id, userDetails.getUser());
    }
}

👉 Post Service / Security 적용 전

@Service
@RequiredArgsConstructor
public class PostService {
    private final PostRepository postRepository;
    private final UserRepository userRepository;

    private final PostLikeRepository postLikeRepository;

    @Transactional
    public PostResponseDto createPost(PostRequestDto postRequestDto, String requestedUsername) {

        User user = userRepository.findByUsername(requestedUsername).orElseThrow(
                () -> new IllegalArgumentException("존재하지 않는 사용자 입니다.")
        );

        // 요청받은 Dto로 DB에 저장할 객체 만들기
        Post post = postRepository.save(new Post (postRequestDto, user));
        return new PostResponseDto(post);
    }

    @Transactional(readOnly = true)
    public List<PostResponseDto> getAllBlogs() {
        List<Post> posts = postRepository.findAllByOrderByModifiedAtDesc();
        List<PostResponseDto> postResponseDto = new ArrayList<>();
        for (Post post : posts){
            postResponseDto.add(new PostResponseDto(post));
        }
        return postResponseDto;
    }

    @Transactional(readOnly = true)
    public PostResponseDto getPosts(Long id) {
        Post post = postRepository.findById(id).orElseThrow(
                () -> new IllegalArgumentException("해당 게시글이 존재하지 않습니다.")
        );
        return new PostResponseDto(post);
    }

    @Transactional
    public PostResponseDto updatePost(Long postId, PostRequestDto requestDto, String requestedUsername) {

        User user = userRepository.findByUsername(requestedUsername).orElseThrow(
                () -> new IllegalArgumentException("존재하지 않는 사용자입니다.")
        );
        Post post = postRepository.findByIdAndUserId(postId, user.getId()).orElseThrow(
                () -> new IllegalArgumentException("해당 게시글이 존재하지 않습니다.")
        );

        post.update(requestDto);
        return new PostResponseDto(post);
    }

    public ResponseEntity<String> deletePost(Long id, String requestedUsername) {

        User user = userRepository.findByUsername(requestedUsername).orElseThrow(
                () -> new IllegalArgumentException("존재하지 않는 사용자입니다.")
        );

        Post post = postRepository.findByIdAndUserId(id, user.getId()).orElseThrow(
                () -> new IllegalArgumentException("해당 게시글이 존재하지 않습니다.")
        );

        postRepository.deleteById(id);
        return new ResponseEntity<>("삭제 성공!", HttpStatus.OK);
    }

    @Transactional
    public ResponseEntity<String> likeOrDislikePost(Long postId, String requestedUsername) {
        User user = userRepository.findByUsername(requestedUsername).orElseThrow(
                () -> new IllegalArgumentException("존재하지 않는 사용자입니다.")
        );
        Post post = postRepository.findById(postId).orElseThrow(
                () -> new IllegalArgumentException("해당 게시글이 존재하지 않습니다.")
        );

        List<PostLike> postLikes = postLikeRepository.findByUsernameAndPostId(requestedUsername, postId);
        if (postLikes.isEmpty()) {
            PostLike postLike = postLikeRepository.save(new PostLike(requestedUsername, post));
            return new ResponseEntity<>("해당 게시글에 좋아요를 했습니다.", HttpStatus.OK);
        } else {
            postLikeRepository.deleteByUsername(requestedUsername);
            return new ResponseEntity<>("좋아요를 취소하였습니다.", HttpStatus.OK);
        }
    }
}

 

👉 Post Service / Security 적용 후

@Service
@RequiredArgsConstructor
public class PostService {
    private final PostRepository postRepository;
    private final UserRepository userRepository;
    private final PostLikeRepository postLikeRepository;

    @Transactional
    public PostResponseDto createPost(PostRequestDto postRequestDto, User user) {

        System.out.println("PostService.createPost");
        System.out.println("user.getUsername() = " + user.getUsername());

        // 요청받은 DTO 로 DB에 저장할 객체 만들기
        Post post = postRepository.saveAndFlush(new Post(postRequestDto, user));

        return new PostResponseDto(post);
    }

    @Transactional(readOnly = true)
    public List<PostResponseDto> getAllPost() {
        List<Post> posts = postRepository.findAllByOrderByModifiedAtDesc();
        List<PostResponseDto> postResponseDto = new ArrayList<>();
        for (Post post : posts){
            postResponseDto.add(new PostResponseDto(post));
        }
        return postResponseDto;
    }

    @Transactional(readOnly = true)
    public PostResponseDto getPosts(Long id) {
        Post post = postRepository.findById(id).orElseThrow(
                () -> new IllegalArgumentException("해당 게시글이 존재하지 않습니다.")
        );
        return new PostResponseDto(post);
    }

    @Transactional
    public PostResponseDto updatePost(Long id, PostRequestDto requestDto, User user) {

        System.out.println("PostService.updatePost");
        System.out.println("user.getUsername() = " + user.getUsername());

        Post post = postRepository.findByIdAndUserId(id, user.getId()).orElseThrow(
                () -> new IllegalArgumentException("해당 게시글이 존재하지 않습니다.")
        );

        post.update(requestDto);
        return new PostResponseDto(post);
    }

    @Transactional
    public ResponseEntity<String> deletePost(Long id, User user) {

        Post post = postRepository.findByIdAndUserId(id, user.getId()).orElseThrow(
                () -> new IllegalArgumentException("해당 게시글이 존재하지 않습니다.")
        );

        postRepository.deleteById(id);
        return new ResponseEntity<>("해당 게시글이 삭제되었습니다.", HttpStatus.OK);
    }

    @Transactional
    public ResponseEntity<String> likeOrDislikePost(Long id, User user) {
        Post post = postRepository.findByIdAndUserId(id, user.getId()).orElseThrow(
                () -> new IllegalArgumentException("해당 게시글이 존재하지 않습니다.")
        );

        List<PostLike> postLikes = postLikeRepository.findByUsernameAndPostId(user.getUsername(), id);
        if (postLikes.isEmpty()) {
            PostLike postLike = postLikeRepository.save(new PostLike(user.getUsername(), post));
            return new ResponseEntity<>("해당 게시글에 좋아요를 했습니다.", HttpStatus.OK);
        } else {
            postLikeRepository.deleteByUsername(user.getUsername());
            return new ResponseEntity<>("해당 게시글에 좋아요를 취소하였습니다.", HttpStatus.OK);
        }
    }

}

 


🙋‍♂️ 소감 : 

로직 자체는 변경이 되지 않고, Security를 적용하니

User 객체를 바로 가지고와서 토큰을 검증하고, User가 있는지 없는지 확인을 하고,

그걸로 다시 User Database에 접근해서 가지고오는 행위들이 JwtAuthFilter에서 수행이 되고,

인증이 완료된 그 User의 정보를 Controller 쪽으로 가지고 와서 받아오니 확실히 코드가 많이 줄어들었다,

😈 아는 내용이라고 그냥 넘어가지 않기! 😈

'❤️‍🔥TIL (Today I Learned)' 카테고리의 다른 글

[TIL] 2023-01-05(49day)  (0) 2023.01.06
[TIL] 2023-01-04(48day)  (0) 2023.01.04
[TIL] 2023-01-02(46day)  (0) 2023.01.02
[TIL] 2022-12-30(45day)  (0) 2023.01.01
[TIL] 2022-12-29(44day)  (0) 2022.12.29

댓글