hanghae99/프로젝트

[Spring Boot + Mustache] 템플릿 엔진 적용 시 겪은 문제와 해결 방법

욘아리 2024. 2. 28. 00:16

내가 선택한 프로젝트는 기본적인 프론트 구현이 요구사항에 포함되어 있었다. 따라서 백엔드의 REST API 코드를 어느 정도 작성한 후에는 문법이 간결한 Musatche 서버 템플릿 엔진을 사용해 화면단을 만들기 시작했다. 그러나 로그인 이후에 토큰이 정상적으로 받아와지지 않아 오류가 발생하였고, 이후의 화면 구현을 작업할 수 없었다.

 

❓ 문제 상황

로그인 후 메인페이지로 이동했을 때 403 Forbidden 오류 발생

 

1. 내가 작성한 토큰 처리 방식

 

✔️ 백엔드 : 로그인 성공하면 헤더에 토큰을 추가하고 헤더에서 토큰 추출해서 인증

✔️ 프론트 : 로그인 성공하면 토큰을 응답받아 로컬 스토리지에 저장

// 로그인 클릭 이벤트 감지!
LoginBtn.addEventListener("click", function () {
  // 사용자 객체 생성
  const user = {
    email: document.querySelector("#user-email").value,
    password: document.querySelector("#user-password").value,
  };
  // fetch() - 비동기 통신을 위한 API
  const url = "/api/auth/login";
  fetch(url, {
    method: "post",
    body: JSON.stringify(user),
    headers: {
      "Content-Type": "application/json",
    },
  })
    .then((response) => {
      if (response.ok) {
        return response.json(); // 로그인 성공 시 토큰을 받아옴
      } else {
        response.json().then((errorData) => {
          alert(`로그인 실패: ${errorData.message}`);
        });
        throw new Error("로그인 실패");
      }
    })
    .then((data) => {
      // 토큰을 localStorage 또는 쿠키에 저장
      localStorage.setItem("accessToken", data.accessToken);
      alert("로그인 성공");
      window.location.href = "/home";
    })
    .catch((error) => {
      console.error(error);
    });
});

 

2. 토큰이 로컬 스토리지에 저장되는 것은 확인. 그러나 home 화면으로 이동 시 403 Forbidden 오류 발생

로컬 스토리지에 저장된 토큰

 

3. 인증 필터에 로그를 찍어서 확인해 본 결과 페이지 이동 시 헤더에 토큰이 담겨 있지 않아 발생한 문제로 판단.

 

💡 해결 방법

1. 헤더에 토큰이 담기지 않는 문제를 해결하기 위해 토큰 처리 방식 변경

 

✔️ 프론트 : 헤더에서 토큰을 가져와 쿠키에 저장하도록 변경

$.ajax({
  // ...
  success: function (response, textStatus, request) {
    // 헤더에서 토큰 추출
    const tokenHeader = request.getResponseHeader("Authorization");
    const token = tokenHeader ? tokenHeader.substring(7) : null;

    // 토큰을 쿠키에 저장
    Cookies.set("accessToken", token, { expires: 7, path: "/" });

    alert("로그인 성공");
    window.location.href = "/home";
  },
  //...
});


✔️ 백엔드 : 헤더에 토큰이 없으면 쿠키에서 토큰을 추출하는 방식으로 변경

try {
    String token = null;
    // 헤더에서 토큰 추출
		final String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
    if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
        token = parseBearerToken(authorizationHeader);
    }

    // 헤더에 토큰이 없으면 쿠키에서 토큰 추출
    if (token == null) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("accessToken")) {
                    token = cookie.getValue();
                    break;
                }
            }
        }
    }

 

👉 쿠키를 사용한 토큰 저장은 서버와 클라이언트 간의 효율적인 통신을 가능하게 하고 헤더에 토큰을 담지 못하는 문제 해결

 

2. 정적 리소스 허용 및 favicon 설정

 

✔️ 정적 리소스에 대한 시큐리티 허용을 추가하여 프론트에서 필요한 리소스에 자유롭게 접근할 수 있도록 함.

 

✔️ favicon을 명시하여 브라우저가 웹 페이지의 아이콘을 올바르게 로드할 수 있도록 함.

<!--favicon.ico-->
<link rel="icon" href="data:;base64,=">

 

✌️ 화면단 결과물

✔️ 회원가입 페이지

 

✔️ 로그인 페이지

 

✔️ 게시물 목록 페이지

 

✨👩‍💻 ✨

로그인 이후 인증 관련 오류 해결을 통해 프론트엔드와 백엔드 간의 연결, 그리고 토큰 처리 방식에 대한 이해를 얻게 되었다. 처음에는 프론트 구현이 막혀버려서 어려움을 느꼈지만, 토큰 처리 방식을 분석하고 수정함으로써 문제를 충분히 해결할 수 있었다. 이 경험을 통해 간단한 프론트 구현이라도 프론트와 백의 상호 작용 과정을 경험하고, SSR 방식으로 인증 및 인가를 구현해 볼 수 있는 좋은 기회가 되었다.