[#28] 쇼핑몰 연동 실습 - 다중 서버 세션 문제 해결 + 사용자 인증

2025. 3. 6. 16:52·LG 유플러스 유레카 SW/Spring

📍 다중 서버에서 세션 문제 해결하기 

Frontend

1️⃣ axios 설정

axios는 데이터를 자동으로 json 타입으로 전송해줌

  • index.html
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

2️⃣ credential 설정

  • index.js
window.onload = async () => {
  axios.defaults.withCredentials = true; // Axios가 요청을 보낼 때, 쿠키 및 인증 정보를 포함하도록 설정하는 옵션
  
  // .. 생략
};

3️⃣ login 요청을 axios로 변경

// 로그인
document.getElementById("loginBtn").addEventListener("click", async () => {
  const email = document.getElementById("loginEmail").value;
  const pwd = document.getElementById("loginPwd").value;
  const data = { email, pwd };

  let response = await axios.post("http://localhost:8080/login", data);
  console.log(response);
  alert(response.data.msg);
});

 

Backend

1️⃣ CORS 에러 잡기

  • src/main/java/com.shop.cafe/MyConfig.java 생성
package com.shop.cafe;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyConfig implements WebMvcConfigurer {
	@Override
	public void addCorsMappings(CorsRegistry registry) {
		WebMvcConfigurer.super.addCorsMappings(registry);
		registry.addMapping("/**") // 모든 URL 매핑
		.allowedOrigins("http://127.0.0.1:5500/") // 허용할 URL
		.allowedMethods("*") // 허용할 HTTP 요청 방식
		.allowedHeaders("*") // 허용할 헤더
		.allowCredentials(true); // 쿠키, 세션 허용
	}
}

 

🙋🏻 사용자 인증

로그인 화면 갱신 문제

  • 페이지 새로 고침 시, 화면에서 로그인이 풀림
  • 프론트 서버에 새롭게 html 을 요청하기 때문에 브라우저의 js 내용이 다 날아감
  • 쿠키에 저장된 세션 정보도 다 날아감 ~
  • 하지만 서버에서는 여전히 로그인이 유효함..!

➡️ 사용자 정보를 클라이언트에 저장하고 로그인 유지하기!

모두 위험한 방법이지만 cookie > session storage > ... 에 저장하는 것이 그나마 덜 위험

- 쿠키는 새로고침하면 새롭게 갱신됨
- 세션 스토리지는 새로고침을 해도 해당 브라우저 영역이 남아있으면 데이터가 계속 남아있음 (단, 브라우저 탭이 닫히면 데이터 사라짐)

 

䷍ session storage 사용해보기

Frontend

  • 브라우저를 새로고침하면 화면의 login이 풀려보이는 문제를 sessionStorage로 해결하기
window.onload = async () => {
  // Session Storage에 저장된 사용자 정보 가져와서 로그인 유지하기
  const email = sessionStorage.getItem("email");
  if (email) {
    document.getElementById("loginSpan").innerHTML =
      email + ` <button id="logout">logout</button>`;
  }

  axios.defaults.withCredentials = true; // Axios가 요청을 보낼 때, 쿠키 및 인증 정보를 포함하도록 설정하는 옵션
  let productList = await fetch("http://localhost:8080/getAllProducts", {
    method: "GET",
  });
  productList = await productList.json();
  console.log(productList);
  if (productList) {
    let productListDiv = ``;
    productList.forEach((item) => {
      productListDiv += `<div class="card mt-2" style="width: 10rem;">
                          <img src="img/${item.pimg}" class="card-img-top" alt="${item.prodname}" height="150">
                          <div class="card-body">
                            <b class="card-title">${item.prodname}</b><br>
                            <span class="card-text text-danger">${item.price}원</span>
                            <a href="#" class="btn btn-outline-info" id="addCart">장바구니 담기</a>
                          </div>
                        </div>`;
    });
    document.getElementById("productListDiv").innerHTML = productListDiv;
  }
};

// .. 생략

// 로그인
document.getElementById("loginBtn").addEventListener("click", async () => {
  const email = document.getElementById("loginEmail").value;
  const pwd = document.getElementById("loginPwd").value;
  const data = { email, pwd };

  let response = await axios.post("http://localhost:8080/login", data);
  console.log(response);
  alert(response.data.msg);

  if (response.data.msg === "ok") {
    const modal = bootstrap.Modal.getInstance(
      document.getElementById("loginModal")
    );
    modal.hide();
    document.getElementById("loginSpan").innerHTML =
      email + ` <button id="logout">logout</button>`;

    // Session Storage 사용해서 로그인한 사용자 정보 저장
    window.sessionStorage.setItem("email", email);
  }
});
  • logout 버튼 만들어 sessionStorage의 정보 삭제하기
// 로그아웃
document.getElementById("loginSpan").addEventListener("click", (event) => {
  if (event.target.id === "logout") {
    sessionStorage.removeItem("email"); // Session Storage에 저장된 사용자 정보 삭제
    window.location.reload(); // 화면 갱신
  }
});

 

백엔드 서버로부터 받은 JSESSIONID를 저장했어도 다음 요청 시 쿠키를 가지고 가지 못하는 문제

🥲 다중 서버이면 쿠키에 저장된 JSESSIONID가 자동으로 포함되어 오지 않음

 

해결 1: 구조 변경 방법

Backend

1️⃣ MyConfig.java에서 credential 해제

2️⃣ 모든 Controller에서 @CrossOrigin 해제

3️⃣ src/main/resources/static 폴더에 html, css, js 저장

4️⃣ index.js에서 axios의 credential 해체, 요청 url을 상대 경로로 바꾸기

본인은 3번 과정만 해도 잘 동작이 되었음 !

 

해결 2: 토큰으로 해결하기

https://nueos.tistory.com/187

 

[학습블로깅 #31] 토큰 인증 방식

토큰 인증 방식➡️ 백엔드 서버로부터 받은 JSESSIONID를 저장했어도 다음 요청 시 쿠키를 가지고 가지 못하는 문제 해결 방법클라이언트가 로그인 요청을 보냄서버가 사용자 정보를 검증하고 토

nueos.tistory.com

 

728x90
반응형

'LG 유플러스 유레카 SW > Spring' 카테고리의 다른 글

[#33] RESTful 방식 + Swagger 사용  (0) 2025.03.14
[#31] 토큰 인증 방식  (0) 2025.03.11
[#30] XSS/Tabnabbing 공격  (0) 2025.03.10
[#29] 쇼핑몰 연동 실습 - SQL Injection + Connection Pool  (1) 2025.03.07
[#27] 쇼핑몰 연동 실습 - 회원가입/로그인  (1) 2025.03.05
'LG 유플러스 유레카 SW/Spring' 카테고리의 다른 글
  • [#31] 토큰 인증 방식
  • [#30] XSS/Tabnabbing 공격
  • [#29] 쇼핑몰 연동 실습 - SQL Injection + Connection Pool
  • [#27] 쇼핑몰 연동 실습 - 회원가입/로그인
nueos
nueos
  • nueos
    nueos 공부 기록
    nueos
  • 전체
    오늘
    어제
    • 분류 전체보기 (191)
      • 해커톤 (1)
      • 네이버 BoostCamp (6)
      • LG 유플러스 유레카 SW (3)
        • React (21)
        • TypeScript (2)
        • JavaScript (2)
        • HTML+CSS (5)
        • Spring (7)
        • Java (6)
        • SQL (2)
        • Algorithm (8)
        • CX (6)
        • Git (2)
        • 프로젝트 (2)
        • 스터디 (9)
        • 과제 (8)
        • 특강 (1)
      • React (3)
      • Next (0)
      • Javascript (2)
      • HTML (2)
      • CSS (9)
      • Algorithm (6)
      • Database (0)
      • OS (13)
      • C++ (24)
      • Python (1)
      • jQuery (1)
      • Django (1)
      • Git (1)
      • 개발 지식 (3)
      • 정보 보안 (22)
      • 포렌식 (1)
      • 암호 (2)
      • 기타 (4)
      • 패스트캠퍼스 FE 프로젝트십 (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    큐
    exhaustive search
    기술로바꾸는세상
    스택
    Queue
    완전 탐색
    제주해커톤
    힙
    제주지역혁신플랫폼지능형서비스사업단
    heap
    디지랩챌린지
    디지털혁신
    Stack
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
nueos
[#28] 쇼핑몰 연동 실습 - 다중 서버 세션 문제 해결 + 사용자 인증
상단으로

티스토리툴바