[이상형 월드컵 프로젝트 문제 해결] 비동기로 유저 정보 받다가 발생한 문제

KangHo Lee's avatar
Dec 30, 2024
[이상형 월드컵 프로젝트 문제 해결] 비동기로 유저 정보 받다가 발생한 문제

1. 유저 권한에 따라 상단 메뉴가 바뀌도록 설정하기 위해 유저 정보를 JSON으로 보내는 컨트롤러 설정

// REST API로 만들어서 navbar.mustache에서 로그인 여부와 권한 판별 용 데이터 전송 @GetMapping("/api/authentication") public ResponseEntity<?> checkLogin(@AuthenticationPrincipal User user) { UserResponse.UserInfoDTO userInfoDTO = userService.getUserInfo(user); // JSON으로 전송 return new ResponseEntity<>(Resp.ok(userInfoDTO), HttpStatus.OK); }
ublic class Resp<T> { private Boolean success; private String message; private T body; public static <T> Resp<T> ok(T body) { return new Resp<>(true, "성공", body); } public static <T> Resp<T> fail(String message) { return new Resp<>(false, message, null); } }`
public class UserResponse { @Data public static class UserInfoDTO { private Integer id; private String email; private String nickname; private Timestamp createdAt; private Boolean isDeleted; public UserInfoDTO(User user) { this.id = user.getId(); this.email = user.getEmail(); this.nickname = user.getNickname(); this.createdAt = user.getCreatedAt(); this.isDeleted = user.getIsDeleted(); } } }

2. 로그인 여부에 따라 메뉴 변화하는 JavaScript 작성

let navbarRightMenu = document.querySelector('.navbar-right-menu'); getAuthentication(); // 비동기로 로그인한 유저 정보 가져오기 async function getAuthentication() { // API 요청 let response = await fetch(`http://localhost:8080/api/authentication`, { method: "get", }); let responseData = await response.json(); let userInfo = responseData; // user if (userInfo == null) { navbarRightMenu.innerHTML=` <li class="nav-item"> <a class="nav-link common-hover-primary" href="/login-form">LogIn</a> </li> <li class="nav-item"> <a class="nav-link common-hover-primary" href="/signup-form">회원가입</a> </li> `; } else if (userInfo != null) { navbarRightMenu.innerHTML=` <li class="nav-item"> <a class="nav-link common-hover-primary" href="#">회원정보수정</a> </li> <li class="nav-item"> <a class="nav-link common-hover-primary" href="/logout">LogOut</a> </li> `; } }
  • 하지만 로그인 여부와 관계 없이 메뉴는 일정하게 나왔습니다.
  • if 조건이 잘못 되었나 생각하며 userInfo.isDeleted = false 조건, userInfo.isDeleted == false조건도 걸어보았지만 결과는 같았습니다.

3. SSR 방식으로 변화

  • 비동기 방식(CSR)로 안 되기 때문에 SSR로 변경했습니다.
application.properties
# 4. mustache expose spring.mustache.servlet.expose-session-attributes=true spring.mustache.servlet.expose-request-attributes=true
  • mustache 파일에서 세션과 리퀘스트에 접근 가능하게 설정
<!-- 오른쪽 메뉴 --> <ul class="navbar-nav ms-auto navbar-right-menu"> <!-- 로그인 여부와 권한 판별 --> {{^sessionUser}} <li class="nav-item"> <a class="nav-link common-hover-primary" href="/login-form">LogIn</a> </li> <li class="nav-item"> <a class="nav-link common-hover-primary" href="/signup-form">회원가입</a> </li> {{/sessionUser}} {{#sessionUser}} <li class="nav-item"> <a class="nav-link common-hover-primary" href="/signup-form">회원정보수정</a> </li> <li class="nav-item"> <a class="nav-link common-hover-primary" href="/logout">LogOut</a> </li> {{/sessionUser}} </ul>

4. 다른 팀원이 비동기로 메뉴 변화 성공했다는 이야기

  • 콘솔 로그를 확인해보라는 조언을 듣고 log을 확인해봤습니다.
notion image
// API 요청 let response = await fetch(`http://localhost:8080/api/authentication`, { method: "get", }); let responseData = await response.json(); let userInfo = responseData.body;
  • let userInfo = responseData.body
    • .body를 빼먹어서 안 되는 상황이었습니다.

5. 스프링 사용 전 서블릿에서 작업하던 코드 습관 문제

@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); String user_id = (String) session.getAttribute("user_id"); List<Orders> ordersList = ordersService.selectByUserId(user_id); resp.setHeader("Content-Type", "application/json; charset=utf-8"); JsonMapper jsonMapper = new JsonMapper(); String json = jsonMapper.writeValueAsString(ordersList); PrintWriter pw = resp.getWriter(); pw.print(json); pw.flush(); }
  • 이런 코드로 데이터를 그대로 전송하다가 Resp라는 객체의 body에 담는 코드를 처음 써보면서 생긴 문제였습니다.

6. 배운 점

  • console.log와 System.out.println의 중요성을 다시 한 번 깨닫게 되었습니다.
 
Share article

devleekangho