본문 바로가기

Spring Boot 수업 정리

Spring boot 6일차

로그인기능 까지 구현해놨으니까 이제 권한 별로 필요한 기능 구현

 

● Header에 로그인 했을때랑 안했을 때 보이는 카테고리가 달라지게 설정

  <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav me-auto mb-2 mb-lg-0">
          <li class="nav-item" sec:authorize="isAuthenticated()">
            <a class="nav-link" href="/board/register">BoardRegister</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="/board/list">BoardList</a>
          </li>
          <th:block sec:authorize="isAnonymous()">
            <li class="nav-item" >
              <a class="nav-link" href="/user/register">SignUp</a>
            </li>
            <li class="nav-item" >
              <a class="nav-link" href="/user/login">Login</a>
            </li>
          </th:block>
          <li class="nav-item" sec:authorize="hasRole('ROLE_ADMIN')">
            <a class="nav-link" href="/user/list">UserList</a>
          </li>
          <li class="nav-item" sec:authorize="isAuthenticated()">
              <a class="nav-link" href="/user/modify"
                 th:with="auth=${#authentication.getPrincipal()}">
                [[${auth.userVO.nickName}]] Info Modify
              </a>
          </li>
          <li class="nav-item" sec:authorize="isAuthenticated()">
            <a class="nav-link" href="/user/logout">Logout</a>
          </li>

        </ul>
      </div>

 

로그인을 안했을 때는 회원가입과 로그인이 보이도록, 로그인을 했을 때는 글쓰기, 로그아웃, 정보수정이 보이도록 설정하고  ADMIN 권한 까지 있으면 UserList를 볼 수 있도록 구성 정보수정에는 나의 닉네임을 앞에 표시하도록 하였음.

 

시큐리티 권한관련 태그들을 쓰기위해서는 네임스페이스 설정 필수.

xmlns:sec="http://www.thymeleaf.org/extras/spring-security

 

● 글 작성을 할 때 작성자를 회원 닉네임으로 고정할 수있도록 해주고 상세페이지에 댓글 부분은 로그인을 하지않으면 댓글 POST부분을 막아두고 로그인하면 보일 수 있도록 한다음 댓글 작성자에도 닉네임을 넣을 수 있도록 함.

 <input type="text" class="form-control" id="w" name="writer" readonly="readonly" th:value="${#authentication.getPrincipal().userVO.nickName}">
      <th:block sec:authorize="isAuthenticated()">
       <div class="input-group mb-3">
           <span class="input-group-text" id="cmtWriter" th:text="${#authentication.getPrincipal().userVO.nickName}"></span>
           <input type="text"  id="cmtText" class="form-control" placeholder="Add Comment" aria-label="Comment" aria-describedby="basic-addon1">
           <button type="button" id="cmtAddBtn"  class="btn btn-outline-success">post</button>
       </div>
       </th:block>

 

● 댓글 수정 / 삭제 버튼도 본인 댓글에만 보이도록 설정

 

- 먼저 유저의 닉네임을 따로 사용하기위해 스크립트를 열어서 따로 권한이있을때, 해당 유저의 닉네임을 저장 할 수 있도록함.

       <th:block sec:authorize="isAuthenticated()"
                  th:with="auth=${#authentication.getPrincipal().userVO.nickName}">
            <script th:inline="javascript">
                let nickName = [[${auth}]];
                console.log(nickName);
            </script>
        </th:block>

 

- 댓글 js에서 댓글 버튼 출력부분에 if를 걸어서 닉네임이 작성자와 같으면 버튼이 보이도록설정.

if(nickName === cvo.writer){
     li += `<div class="d-grid gap-2 d-md-flex justify-content-md-end">`;
     li += `<button type="button" data-cno=${cvo.cno} class="btn btn-outline-warning btn-sm mod" data-bs-toggle="modal" data-bs-target="#myModal">%</button>`;
     li += `<button type="button" data-cno=${cvo.cno} class="btn btn-outline-danger btn-sm del">X</button>`;
     li += `</div>`;
}

 

● 어드민 계정에 UserList 부터 구현

 

- 일단 어드민계정에 권한을 DB에서 넣어주고

insert into auth (email, auth) values('1111@naver.com','ROLE_ADMIN');

 

- 유저객체의 리스트를 가져와서 Model을 이용해서 추가할 수 있게 하는데 getList로 가져올 때 권한도 함께 가져올 수 있도록 해야함.

    @GetMapping("/list")
    public void list(Model m) {
        List<UserVO> userList = usv.getList();

        m.addAttribute("userList", userList);
    }
    @Transactional
    @Override
    public List<UserVO> getList() {

        List<UserVO> userList = userMapper.getList();

        for(UserVO userVO : userList) {
            userVO.setAuthList(userMapper.selectAuths(userVO.getEmail()));
        }
        return userList;
    }

 

- 유저의 list화면을 구성.

<div layout:fragment="content" class="container-md" >
  <h1>UserList</h1>

  <div class="row row-cols-1 row-cols-md-3 g-4">
    <th:block th:each="uvo:${userList}">
      <div class="col">
        <div class="card">
          <img th:src="@{/image/사람2.png}" class="card-img-top" alt="...">
          <div class="card-body">
            <h4 class="card-title">[[${uvo.email }]]</h4>
              <span style="margin-right : 3px"  th:each="avo:${uvo.authList }" class="badge text-bg-info">[[${avo.auth }]]</span>
            <br><br> <p class="card-text">가입일 : [[${uvo.regDate }]]</p>
            <p>마지막 로그인 : [[${uvo.lastLogin }]]</p>

          </div>
        </div>
      </div>
    </th:block>
  </div>
</div>

 

● 본인 정보에 들어가서 정보수정이가능하도록 구현

 

- Principal(로그인 한 유저 정보)를 가져와서 수정을위해 form태그안에 넣어서 화면을 구성해주고 

  <th:block th:with="uvo=${#authentication.getPrincipal().userVO}" >
    <form action="/user/modify" method="post" >
      <input type="hidden" name="email" th:value="${uvo.email }">
      <div class="card mb-3" style="max-width: 540px; margin: 0 auto;">
        <div class="row g-0">
          <div class="col-md-4">
            <img style="margin-top : 35px; " src="/image/사람2.png" class="img-fluid rounded-start"
                 alt="...">
          </div>
          <div class="col-md-8">
            <div class="card-body">
              <h5 class="card-title">
                <input style="margin-bottom : 3px;" type="text" id="e" name="nickName" th:value="${uvo.email }" readonly="readonly">
                <input style="margin-bottom : 3px;" type="text" id="n" name="nickName" th:value="${uvo.nickName }">
                <input type="text" id="p" name="pwd" placeholder="password...">
              </h5>
              <span style="margin-right : 3px"  th:each="avo:${uvo.authList }" class="badge text-bg-info">[[${avo.auth }]]</span>
              <p class="card-text">가입일 : [[${uvo.regDate }]]</p>
              <p class="card-text">
                <small class="text-body-secondary">마지막 로그인 :
                  [[${uvo.lastLogin }]]</small>
              </p>
              <button type="submit" class = "btn btn-primary btn-sm">modify</button>
              <a href="/user/delete"><button type="button" class = "btn btn-danger btn-sm">delete</button></a>
            </div>
          </div>
        </div>
      </div>
    </form>



  </th:block>

 

- 컨트롤러에서 modfiy 페이지로 넘어갈 수 있게, 그리고 화면에서 받아온 정보로 update 해서 수정을 진행 할 수 있도록함

정보수정을 할 때 비밀번호를 입력하지않았을 때와 비밀번호를 입력했을 때를 따로진행해서 입력하면 암호화를 해준다음에 update 할 수있도록 함. 수정이후에는 로그아웃.

@GetMapping("/modify")
public void modify() {}

@PostMapping("/modify")
public String modify(UserVO userVO) {

    log.info(">>> modfiy userVO >> {}" ,userVO);

    int isOk = 0;

    if(userVO.getPwd() == null || userVO.getPwd().isEmpty()) {
            // 비번 없이 업데이트 진행
            isOk = usv.modifyNoPwd(userVO);
    }else {
            // 비번 암호화 후 업데이트 진행
          userVO.setPwd(passwordEncoder.encode(userVO.getPwd()));
          isOk = usv.modify(userVO);
        }   
         return "redirect:/user/logout";
    }

 

● 유저 회원탈퇴 (삭제) 구현

 

- Principal을 이용해서 로그인한 유저정보를 가져와서 getName으로 아이디(email)을 가져와 저장하고 email을 받아서 해당 유저의 객체를 가져와서 지울 수 있도록함 지울 때 권한도 함께 지워주어야함. 삭제 후 로그아웃.

   @GetMapping("/user/delete")
    public String delete(Principal principal) {

        String email = principal.getName();

        int isOk = usv.delete(email);

        return "redirect:/user/logout";
    }

'Spring Boot 수업 정리' 카테고리의 다른 글

Spring Boot 5일차  (1) 2024.11.18
Spring Boot 4일차  (0) 2024.11.15
Spring boot 3일차  (3) 2024.11.14
Spring Boot 2일차  (1) 2024.11.13
Spring Boot 1일차  (0) 2024.11.13