inblog logo
|
codingb
    Spring

    v4 - 권한 처리

    coding S's avatar
    coding S
    Mar 16, 2024
    v4 - 권한 처리

    터질만한거 잡으러 다니자!

     

    [ User 파트 ]

    1. 회원가입

    💡
    회원가입 시에 터질만한 것 → 중복된 id로 또다시 가입하는 것! [ 유니크 제약 조건 위배! ]
    notion image
     

    [ 기존 코드 ]

    notion image
    notion image
    💡
    어디서 오류가 터지나? persist 할 때 터짐. 그렇다고 여기서 try-catch 거는 걸 추천하지 않는다. 레파지토리는 그냥 순수하게 둬라!
     

    [ 방법 1 ]

    @PostMapping("/join") public String join(UserRequest.JoinDTO requestDTO) { try { userRepository.save(requestDTO.toEntity()); //DataIntegrityViolationException 정확하게 적어줘라!!!!!!!!!!! } catch (DataIntegrityViolationException e) { throw new Exception400("동일한 유저네임이 존재합니다."); } return "redirect:/"; }
    💡
    try-catch로 묶고 터뜨린다.
    💡
    근데 왜 정확하게 적어줘야 할까? 이렇게 안 적어주면 DataIntegrityViolationException 에 해당하는 오류 처리를 못해준다
     

    [ 방법 2 ]

    notion image
    💡
    우린 일단 방법1로 진행한다. 이 외에도 username 300자 넣으면 터진다거나… 그런게 있지만 일단은 패스
     

    [ 오류 화면 띄우기 완료 ]

    notion image
     

    2. 로그인

    @PostMapping("/login") public String login(UserRequest.LoginDTO requestDTO) { try { User sessionUser = userRepository.findByUsernameAndPassword(requestDTO); session.setAttribute("sessionUser", sessionUser); return "redirect:/"; //EmptyResultDataAccessException 정확하게 적어줘라!!!!!!!!!!! } catch (EmptyResultDataAccessException e) { throw new Exception401("유저네임 혹은 비밀번호가 틀렸어요"); } }
    💡
    정상적인 로직은 try에 넣는다. 이걸 안 하면 여기서 if해서 session == null ~~ 뭐 이런 로직을 잔뜩 짜고 있겠지!
     

    [ 오류 화면 띄우기 완료 ]

    notion image
     

    3. 회원정보 수정 폼 (updateform, update는 필요 X)

    notion image
    세션 유저는 절대 null일 수가 없으니... 할 게 없다. 패스!
     
     

    [ Board 파트 ]

    게시글 수정하기 (수정 권한 주기) - update

    @PostMapping("/board/{id}/update") public String update(@PathVariable Integer id, BoardRequest.SaveDTO requestDTO){ User sessionUser = (User) session.getAttribute("sessionUser"); Board board = boardRepository.findById(id); if (sessionUser.getId() != board.getUser().getId()) { throw new Exception403("게시글을 수정할 권한이 없습니다"); } boardRepository.updateById(id, requestDTO.getTitle(), requestDTO.getContent()); return "redirect:/board/"+id; }
    💡
    ssar로 로그인해서, cos가 쓴 글을 수정하려고 하면,
     

    [ 오류 화면 띄우기 완료 ]

    notion image
     

    게시글 수정하기 - update-form

    notion image
    강제로 5번 (없는 게시글)로 들어가면 이렇게 터진다. 이것도 잡아야함! 페이지로 가는 것까지 권한 체크 하는건... 아닌듯... action은 안 되니까 일단 패스 오류가 나는 건 아니니까 try-catch는 아니다
     

    [ 코드 ]

    @GetMapping("/board/{id}/update-form") public String updateForm(@PathVariable Integer id, HttpServletRequest request){ Board board = boardRepository.findById(id); if (board == null) { throw new Exception404("해당 게시글을 찾을 수 없습니다"); } request.setAttribute("board", board); return "board/update-form"; }
     

    [ 화면 확인 ]

    notion image
    notion image
    💡
    근데 언제는 try-catch 하고, 언제는 if로 하고… 일관성이 없어서 별로인 코드
     

    게시글 삭제하기

    @PostMapping("/board/{id}/delete") public String delete(@PathVariable Integer id){ User sessionUser = (User) session.getAttribute("sessionUser"); Board board = boardRepository.findById(id); if (sessionUser.getId() != board.getUser().getId()) { throw new Exception403("게시글을 삭제할 권한이 없습니다"); } boardRepository.deleteById(id); return "redirect:/"; }
     

    [ 오류 화면 띄우기 완료 ]

    notion image
     

    게시글 상세 보기 → true/false (주인이어야만 삭제/수정 버튼이 보여야 함!)

    notion image
    💡
    이거… 나는 ssar인데 cos가 쓴 게시글의 수정/삭제 버튼이 보이네 → 고쳐주자!
    로그인 자체를 안 했음 -> false 로그인은 했는데, 게시글이 주인이면 -> true 게시글의 주인이 아니면 -> false
     

    코드 리팩 과정

    [ 최초의 코드 ]

    @GetMapping("/board/{id}") public String detail(@PathVariable Integer id, HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); Board board = boardRepository.findByIdJoinUser(id); boolean isOwner; if (sessionUser == null) { isOwner = false; }else { if (sessionUser.getId() == board.getUser().getId()) { isOwner = true; } else { isOwner = false; } } request.setAttribute("board", board); return "board/detail"; }

    [ 1차 리팩 ]

    기본을 false로 해놓으면 if (sessionUser == null) { isOwner = false; 이 로직이 필요없음
    @GetMapping("/board/{id}") public String detail(@PathVariable Integer id, HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); Board board = boardRepository.findByIdJoinUser(id); boolean isOwner = false; if (sessionUser != null) { if (sessionUser.getId() == board.getUser().getId()) { isOwner = true; }else { isOwner = false; } } request.setAttribute("board", board); return "board/detail"; }

    [ 2차 ]

    false를 안 줘도 false 니까 else도 날리자
    @GetMapping("/board/{id}") public String detail(@PathVariable Integer id, HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); Board board = boardRepository.findByIdJoinUser(id); // 로그인을 하고 게시글의 주인이면 isOwne가 true가 된다 ! boolean isOwner = false; if (sessionUser != null) { //로그인 했으면 if (sessionUser.getId() == board.getUser().getId()) { isOwner = true; } } request.setAttribute("board", board); return "board/detail"; }
     

    [ 최종 리팩 코드 ]

    @GetMapping("/board/{id}") public String detail(@PathVariable Integer id, HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); Board board = boardRepository.findByIdJoinUser(id); // 로그인을 하고 게시글의 주인이면 isOwner가 true가 된다 ! boolean isOwner = false; if (sessionUser != null) { if (sessionUser.getId() == board.getUser().getId()) { isOwner = true; } } request.setAttribute("isOwner", isOwner); request.setAttribute("board", board); return "board/detail"; }
     

    [ detail.mustache ]

    notion image

    [ 화면 확인 ]

    notion image
    💡
    로그인 안 한 경우
    notion image
    notion image
    💡
    ssar로 로그인 한 경우
     
     
     
    Share article

    codingb

    RSS·Powered by Inblog