[Spring] 숙련 Lv.2 과제

호호빵·2023년 1월 1일
0

2022 Spring HW

목록 보기
3/3
  • User의 역할이 USER, ADMIN 둘 중 하나인데 ADMIN일 때는 포스트의 수정과 삭제를 모두 할 수 있어 다음과 같이 service에서 로직을 구성했다.
  • 토큰을 확인하여 user 정보를 가져오는 것은 controller에서 처리하고 update 부분만을 service에서 처리하려 했다.
  • 반복코드를 줄이고, admin 메소드를 따로 구현했다.

기존 코드

# PostController
@PutMapping("/posts/{id}")
    public PostResponse updatePost(@PathVariable Long id, @RequestBody PostRequest requestDto, HttpServletRequest request) {
        String token = jwtUtil.resolveToken(request);
        Claims claims;

        if (token != null) {
            if (!jwtUtil.validateToken(token)) {
                throw new IllegalArgumentException("토큰값이 잘못되었습니다.");
            }
            claims = jwtUtil.getUserInfoFromToken(token);
            String usernameOfToken = claims.getSubject();

            return postService.updatePost(id, requestDto, usernameOfToken);
        } else {
            throw new IllegalArgumentException("토큰이 존재하지 않습니다.");
        }
    }

# PostService

@Transactional
    public PostResponse updatePost(Long id, PostRequest requestDto, String usernameOfToken) {

        Post post = postRepository.findById(id).orElseThrow(
                () -> new IllegalArgumentException("해당 포스트가 존재하지 않습니다.")
        );

        // 토큰에서 가져온 사용자 정보를 사용하여 DB 조회
        User user = userRepository.findByUsername(usernameOfToken).orElseThrow(
                () -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
        );

        if (post.isWriter(user.getUsername()) || user.isAdmin(user.getRole())) {
            post.update(id, requestDto, user);
            postRepository.save(post);
        } else {
            throw new RuntimeException("해당 유저만 수정할 수 있습니다.");
        }

        return new PostResponse(post, user);
    }

반복되는 것 줄이기

  • JwtService, AuthenticatedUser class을 만들어 controller에서 인증과 인가를 처리하게끔 함.
  • 나중에는 JwtUtil에 메소드를 넣어주고 JwtService는 삭제함
# JwtService

@Service
@RequiredArgsConstructor
public class JwtService {
    private final JwtUtil jwtUtil;

    public AuthenticatedUser validateAndGetInfo(String token) {
        if (jwtUtil.validateToken(token)) {
            Claims claims = jwtUtil.getUserInfoFromToken(token);
            String username = claims.getSubject();
            UserRoleEnum role = UserRoleEnum.valueOf(claims.get("auth").toString());
            return new AuthenticatedUser(role, username );
        } else {
            throw new IllegalArgumentException("Token Error");
        }
    }
 }

@Getter
public class AuthenticatedUser {
    private final UserRoleEnum userRoleEnum;
    private final String username;

    public AuthenticatedUser(UserRoleEnum role, String username) {
        this.userRoleEnum = role;
        this.username = username;
    }
}

admin 메소드 따로 만들기

  • update -> update, adminUpdate
  • delete -> delete, adminDelete

최종 코드

# Controller
@PutMapping("/posts/{id}")
    public PostResponse updatePost(@PathVariable Long id, @RequestBody PostRequest requestDto, HttpServletRequest request) {
        String token = jwtUtil.resolveToken(request);
        AuthenticatedUser authenticatedUser = jwtUtil.validateAndGetInfo(token);
        return postService.updatePost(id, requestDto, authenticatedUser.getUsername());
    }

@PutMapping("/admin/posts/{id}")
    public PostResponse adminUpdatePost(@PathVariable Long id, @RequestBody PostRequest requestDto, HttpServletRequest request) {
        String token = jwtUtil.resolveToken(request);
        AuthenticatedUser authenticatedUser = jwtUtil.validateAndGetInfo(token);

        if (!authenticatedUser.getUserRoleEnum().equals(UserRoleEnum.ADMIN)) {
            throw new IllegalArgumentException("권한이 없습니다.");
        }

        return postService.adminUpdatePost(id, requestDto, authenticatedUser.getUsername());
    }


# Service
@Transactional
    public PostResponse updatePost(Long id, PostRequest requestDto, String username) {

        Post post = postRepository.findById(id).orElseThrow(
                () -> new IllegalArgumentException("해당 포스트가 존재하지 않습니다.")
        );

        // 토큰에서 가져온 사용자 정보를 사용하여 DB 조회
        User user = userRepository.findByUsername(username).orElseThrow(
                () -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
        );

        if (post.isWriter(user.getUsername())) {
            post.update(id, requestDto, user);
            postRepository.save(post);
        } else {
            throw new RuntimeException("해당 유저만 수정할 수 있습니다.");
        }

        return new PostResponse(post, user);
    }

    @Transactional
    public PostResponse adminUpdatePost(Long id, PostRequest requestDto, String username) {

        Post post = postRepository.findById(id).orElseThrow(
                () -> new IllegalArgumentException("해당 포스트가 존재하지 않습니다.")
        );

        // 토큰에서 가져온 사용자 정보를 사용하여 DB 조회
        User user = userRepository.findByUsername(username).orElseThrow(
                () -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
        );

        post.update(id, requestDto, user);
        postRepository.save(post);

        return new PostResponse(post, user);
    }
profile
하루에 한 개념씩

0개의 댓글

Powered by GraphCDN, the GraphQL CDN