Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

관리자 권한 본문

Project/블로그 게시판 만들기

관리자 권한

Seung__ 2021. 10. 14. 22:22

1. 관리자 권한


  • 관리자는 모든 권한을 가지고 있다.
  • 모든 글/댓글에 대한 수정&삭제 권한이 있음.

 

 

2. 권한 level 설정


  • 본격적인 코드 작성에 앞서서 권한의 level을 다음과 같이 수직적(?)으로 수정했다.
  • admin : 모든 글/댓글에 대한 수정/삭제 권한
  • normal : 본인이 작성한 글에 대해 수정/삭제 권한. 본인이 작성한 댓글에 대한 삭제 권한
  • commentOnly : 해당 글에 대해 댓글만 작성 가능. 본인이 작성한 댓글에 대한 삭제 권한.
  • guest : 조회만 가능. 수정/삭제에 대한 모든 권한 없음.   
public interface Authority {

    String admin = "admin"; //모든 권한
    String normal = "normal"; //해당 글 + 본인 댓글에 대한 권한
    String commentOnly = "commentOnly"; //댓글 작성, 본인 댓글만 수정 가능.
    String guest = "guest"; //모든 권한 없음.

}

 

 

3. LoginController


  • admin계정이 로그인 하는 경우 authority에 admin을 지정.
    @PostMapping("/login")
    public String login(@Validated @ModelAttribute("loginForm") LoginForm form, Model model,
                        BindingResult bindingResult, HttpServletResponse response){
        if(bindingResult.hasErrors()){
            return "login/loginForm";
        }

        MemberDto loginMember = loginService.login(form.getLoginId(), form.getPassword());
        if(loginMember == null){
            bindingResult.reject("loginFail", "id또는 pw정보가 맞지 않습니다.");
            return "login/loginForm";
        }

        //로그인 성공
        //관리자 확인
        if(form.getLoginId().equals("admin")){
            loginMember.setAuthority(Authority.admin);
        }
        model.addAttribute("member", loginMember);
        //세션으로 쿠키 처리.
        sessionManager.createSession(loginMember, response);

        return "redirect:/";
    }

 

 

4. PostController


  • 글 목록 조회
    • 접속한 유저가 로그인을 안한 guest면 authority를 guest로 지정.
  • 글 조회
    • 비 로그인 사용자 : guest
    • 로그인 사용자 이나, 사용자의 id와 글 작성한 회원의 id가 다른 경우 : commentOnly
    • 단 이 때 authority가 admin인 경우 authority는 admin으로 수정.
  • 각 메서드에 필요한 권한을 확인 및 세팅.
    @GetMapping
    public String posts(Model model, HttpServletRequest request) {

        MemberDto loginMemberDto = getLoginMember(request);

        List<Post> posts = postService.findAll();
        List<PostDto> postsDto = getPostDtos(posts);

        loginMemberDto = checkNonLoginGuest(loginMemberDto);
        model.addAttribute("member", loginMemberDto);
        model.addAttribute("posts", postsDto);
        model.addAttribute("searchForm", new SearchForm());


        return "post/posts";
    }

    @GetMapping("/{postId}")
    public String post(@PathVariable("postId") Long postId, Model model, HttpServletRequest request){

        Post post = postService.findPostById(postId);
        PostDto postDto = post.postToDto();

        MemberDto loginMemberDto = getLoginMember(request);

        loginMemberDto = checkAuthorization(postId, loginMemberDto);

        List<Comment> comments = post.getComments();
        List<CommentDto> commentDtos = comments.stream()
                .map(comment -> new CommentDto(comment.getId(), comment.getContent(), comment.getMember().memberToDto(),
                        postDto.getId(), comment.getLastModifiedDate())).collect(Collectors.toList());

        model.addAttribute("member", loginMemberDto);
        model.addAttribute("post", postDto);
        model.addAttribute("comments", commentDtos);
        model.addAttribute("commentDto", new CommentDto());

        return "post/post";
    }

    @GetMapping("/search")
    public String search(@RequestParam("keyword") String keyword, Model model, HttpServletRequest request){

        log.info("keyword: {}", keyword);
        MemberDto loginMemberDto = getLoginMember(request);

        List<Post> posts = postService.findByTitleContains(keyword);
        List<PostDto> postsDto = getPostDtos(posts);

        checkNonLoginGuest(loginMemberDto);
        model.addAttribute("member", loginMemberDto);
        model.addAttribute("posts", postsDto);
        model.addAttribute("searchForm", new SearchForm(keyword));
        model.addAttribute("status", status);

        return "post/posts";
    }

    @GetMapping("/new/form")
    public String postForm(Model model, HttpServletRequest request) {
        MemberDto loginMemberDto = getLoginMember(request);

        if (hasNoAuthority(loginMemberDto)) return "redirect:/posts";

        PostDto postDto = new PostDto();
        model.addAttribute("member", loginMemberDto);
        model.addAttribute("post", postDto);

        return "post/addform";
    }

    @PostMapping("/new/form")
    public String addPost(@ModelAttribute("post") PostDto postDto, HttpServletRequest request) {
        MemberDto loginMemberDto = getLoginMember(request);

        if (hasNoAuthority(loginMemberDto)) return "redirect:/posts";

        Member findMember = memberService.findMemberById(loginMemberDto.getId());

        log.info("post1.title : {}", postDto.getTitle());
        log.info("post1.content : {}", postDto.getContent());

        Post post = new Post().dtoToPost(postDto);
        post.setMember(findMember);
        postService.savePost(post);
        memberService.joinMember(findMember);

        log.info("new post.title = {}", post.getTitle());
        log.info("new post.content = {}", post.getContent());
        log.info("new post by : {}", loginMemberDto.getUserId());

        return "redirect:/posts";
    }

    @PostMapping("/{postId}/delete")
    public String deletePost(@PathVariable("postId") Long postId, HttpServletRequest request){
        MemberDto loginMemberDto = getLoginMember(request);

        if (hasNoAuthority(loginMemberDto)) return "redirect:/posts";

        PostDto postDto = postService.findPostById(postId).postToDto();

        postService.deletePost(postId);

        return "redirect:/posts";
    }

    @GetMapping("/{postId}/edit")
    public String editForm(@PathVariable("postId") Long postId, HttpServletRequest request, Model model){
        MemberDto loginMemberDto = getLoginMember(request);

        if (hasNoAuthority(loginMemberDto)) return "redirect:/posts";

        getLoginMemberAndAddToModel(request, model);

        PostDto postDto = postService.findPostById(postId).postToDto();
        model.addAttribute("post", postDto);

        return "post/editform";
    }

    @PostMapping("/{postId}/edit")
    public String editPost(@PathVariable("postId") Long id, @ModelAttribute("post") PostDto postDto
                            ,HttpServletRequest request,Model model, RedirectAttributes redirectAttributes){

        MemberDto loginMemberDto = getLoginMember(request);

        if (hasNoAuthority(loginMemberDto)) return "redirect:/posts";

        Post post = editPostUsingDto(id, postDto);

        model.addAttribute("member", loginMemberDto);
        model.addAttribute("post", post.postToDto());
        redirectAttributes.addAttribute("postID", postDto.getId());
        return "redirect:/posts/{postId}";
    }

    private boolean hasNoAuthority(MemberDto loginMemberDto) {
        if (loginMemberDto == null || loginMemberDto.getAuthority().equals(Authority.guest)) {
            return true;
        }
        return false;
    }

    private MemberDto checkNonLoginGuest(MemberDto loginMemberDto) {
        if (loginMemberDto == null){
            log.info("비 로그인 사용자 접속");
            loginMemberDto = new MemberDto();
            loginMemberDto.setUserId(Authority.guest);
            loginMemberDto.setAuthority(Authority.guest);
        }

        return loginMemberDto;

    }

    private MemberDto checkAuthorization(Long postId, MemberDto loginMemberDto) {

        PostDto postDto = postService.findPostById(postId).postToDto();

        if (loginMemberDto == null){
            log.info("비 로그인 사용자 접속");
            loginMemberDto = new MemberDto();
            loginMemberDto.setUserId(guest);
            loginMemberDto.setAuthority(Authority.guest);

            return loginMemberDto;

        }else if(!loginMemberDto.getId().equals(postDto.getMember().getId())){
            if(loginMemberDto.getAuthority().equals(Authority.admin)){
                loginMemberDto.setAuthority(Authority.admin);
                return loginMemberDto;
            }
            loginMemberDto.setAuthority(Authority.commentOnly);

            return loginMemberDto;
        }else {
            loginMemberDto.setAuthority(Authority.normal);

            return loginMemberDto;
        }

    }

 

 

5.View


  • 글 수정 : guest 이거나 commentOnly인 경우 권한 없음.
 <button class="btn btn-primary" type="button"
                    th:disabled="${member.authority.equals('guest') or member.authority.equals('commentOnly')}"
                    th:onclick="|location.href='@{/posts/{postId}/edit(postId=${post.id})}'|">수정</button>
  • 글 삭제 : guest 이거나 commentOnly인 경우 권한 없음.
           <button class="btn btn-secondary float-end" type="submit"
                    th:disabled="${member.authority.equals('guest') or member.authority.equals('commentOnly')}"
                    th:onclick="|location.href='@{/posts/{postId}/delete(postId=${post.id})}'|">삭제</button>
  • 댓글 삭제 : member.id와 comment.member.id가 동일하거나 admin인 경우 가능
             --> admin 이고 member.id와 comment.member.id가 동일하지 않으면 권한 없음.
            <form th:action="@{/comments/{commentId}/delete?postId={id}(commentId=${comment.id}, id=${post.id})}" th:object="${commentDto}" method="post">
                <button type="submit" class="btn-close" aria-label="Close"
                        th:disabled="${member.id} != ${comment.member.id} and ${member.authority} !='admin'"></button>
            </form>
  • 댓글 입력 : guest인 경우만 권한 없음.
        <div class="input-group mb-3; form-group">
            <input type="text" class="form-control" th:field="*{content}" id="commentString" placeholder="댓글 입력" aria-label="Recipient's username" aria-describedby="button-addon2">
            <button class="btn btn-outline-primary" type="submit" id="button-addon2" th:disabled="${member.userId}=='guest'">입력</button>
        </div>

 

 

6. 결과


  • admin으로 접속한 경우 모든 버튼이 활성화 되어 있음.

  • test로 로그인 한 경우 test1이 작성한 글/댓글에 대한 권한 없음.

 

  • 본인이 작성한 글/댓글에 대한 권한 있음. 어.. 근데 직접 접속하면 가능하다.. 

  • guest인 경우 모든 권한 없음.

 

 

7. url 직접 접속을 통한 다른 사용자 글 수정시도 차단


  • editForm()에서 사용할 검증 로직을 살짝 보완 해 주자.
  • 해당 글에 권한이 없어도 현재는 url을 통해 수정이 가능한 상태이다.
  • 해당 url에 접속하여 editForm()을 호출하는 경우 사용자가 권한이 있는지 재확인 하자.
    @GetMapping("/{postId}/edit")
    public String editForm(@PathVariable("postId") Long postId, HttpServletRequest request, Model model){
        MemberDto loginMemberDto = getLoginMember(request);

        PostDto postDto = postService.findPostById(postId).postToDto();
        log.info("authority : {}", loginMemberDto.getAuthority());

        if (hasNoAuthority(loginMemberDto, postDto)) return "redirect:/posts";

        getLoginMemberAndAddToModel(request, model);

        model.addAttribute("post", postDto);

        return "post/editform";
    }	
    
	private boolean hasNoAuthority(MemberDto loginMemberDto, PostDto postDto) {
        if (loginMemberDto == null || loginMemberDto.getAuthority().equals(Authority.guest)
        || loginMemberDto.getId() != postDto.getMember().getId()) {
            return true;
        }
        return false;
    }

 

8. 앞으로


  • est용 data 서버시작할 때 DB에 올리기
  • Listener
    • createdAt, updatedAt등
  • 게시글에 작성자 표시
  • view 정리
  • 게시글 검색
    • 검색 옵션 추가 : 작성자, 제목 구분
  • 영속성 전이 설정
    • 게시글 삭제
    • 회원 탈퇴
  • 댓글 삭제 버튼
  • 글 수정 기능 추가
  • 대댓글
  • 검증 & 예외처리
    • 회원 가입시 필수 정보 지정.
    • 특수문자, 공백 검증 등(email  형식?)
    • Spring제공 Validator로 변경.
  • 인증처리
    • 로그인한 사용자만 글 & 댓글 작성 가능.
    • 본인이 작성한 글, 댓글만 수정/삭제 가능
    • 관리자는 모든 권한
  • 예외처리
  • 페이징 처리
  • 컬렉션 조회 최적화

 

9. GItHub: 211014 admin


 

GitHub - bsh6463/blog

Contribute to bsh6463/blog development by creating an account on GitHub.

github.com

 

'Project > 블로그 게시판 만들기' 카테고리의 다른 글

Test 추가, gerResultList()  (0) 2021.10.16
SpringInterceptor  (0) 2021.10.15
인증처리 - 본인이 작성한 것만..  (0) 2021.10.13
비 로그인 사용자 처리  (0) 2021.10.12
특수문자 및 공백 검증  (0) 2021.10.12
Comments