Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
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
관리 메뉴

JustDoEat

[vite,spring/문제해결]서버 인증 쿠키데이터를 읽어오지 못하는 현상. 본문

카테고리 없음

[vite,spring/문제해결]서버 인증 쿠키데이터를 읽어오지 못하는 현상.

kingmusung 2024. 8. 15. 20:09

개발환경.

frontend: TypeScripts, React, Vite

Backend: Java, Spring Boot, Flask

Docker

 

해결과정 생략 및 결과만 보실 분들은 맨 아래만 참고 바랍니다.


개요.

API 테스트에서 로그인 후 인증정보를 받아오면, 서버에서 인증정보를 확인 후 인가된 사용자면 API호출이 가능하게 하는 방식이다.

 

Swagger를 이용하여 로그인API를 실행을 하면 인증정보가 생기게 되고, 그 후 다른 API호출을 하게 되면 문제없이 작동이 잘 되었다.

 

하지만 Docker 로 올린 frontend 컨테이너에서 backend(springBoot) 컨테이너로 API호출을 보낼 시 인증 관련 에러가 발생함.

페이지는 리다이렉트 되는데 서버로 부터 원하는 데이터가 넘어오지 않았다.

console.log로 response.data를 찍어봤을 때

 

위와 같이 HTML코드가 응답이 되는 현상을 식별을 하였다. 이 부분은 서버단에서 사용자가 로그인을 하지 않았을 시 로그인 페이지로 리다이렉트 해주는 정적 html 파일을 리턴해주는 현상이라고 한다.

(어쩐지 로그를 더 찍어보면 적어놓지도 않은 /login 400 error라는 에러가 나왔다.)


문제해결

 

일단 사용자가 로그인을 한다면

JSESSIONID라는

 

사실 소통의 부제가 있었다. 인증정보를 SESSION에 준다고 들어서, 개발자도구에 SESSION창에 들어가서 왜 SESSiON이 없지.. 하고 고민을 많이 했었다.

 

혹시나 해서 COOKIES에 들어갔는데 JSESSION이라는 쿠키를 발견하였고 질문을 하였다.. 혹시 세션이 아니라 쿠키에 저장되는 게 아닐까라는 의문이 들어서 다시 백엔드 팀원에게 물어보았다 확인 후... "네 맞습니다 말을 잘못했네요!" 

 

오케이! 이제 문제가 무엇인지 알았다.

 

 

1. Swagger에서 인증 후 쿠키가 잘 넘어오는지 확인 후 Vite에서도 쿠키가 잘 넘어오는지 확인.

Swagger는 오케이 잘 넘어온다. Vite도 테스트 결과 어? 

로그인을 해도 넘어오지 않는다.

 

왜 Cookies가 안 심어지는지 고민해 보자.

 

일단 서버단에서 해본 고민은

"포트번호가 달라서 CORS 설정문제 인가?"

"서버에서 쿠키를 심어주는 로직이 잘못된 건가?"

 

솔직히 서버단에서 문제가 있는 줄 알았다. 하지만 CORS설정 및 쿠키 전달 로직도 잘 되어있는 거 같고 3일째 그 자리에 멈추어 있었다.

그래서 프런트단에서 문제가 있는지 생각을 전환해 보았다.

 

프런트단에서 해본 고민은

"웹사이트 접속 시 "쿠키허용"이라는 문구를 봤었기 때문에, 쿠키를 받는 무언가를 허용을 해야 하나?"

=> 기대도 안 한 고민이었지만 이 부분이 문제의 원인이었다.

 

서버로부터 Cookies를 전달받는 방법.

credentials: 'include' // fetch 요청시 사용
혹은
withCredentials: true, // Axios요청 혹은 XMLHttpRequest 요청시 사용 가능

상황에 맞춰서 사용

 

동일포트 번호가 아닌 CROSS-Origin(다른 포트번호 간 통신)으로

fetch 요청을 할 때 위 부분을 필히 적어주어야 서버로부터 쿠키를 전달받을 수 있다.

 

credentials: 'include'란 

는 웹 브라우저의 fetch API에서 사용하는 옵션으로, 요청을 보낼 때 쿠키와 인증 정보를 포함하도록 설정하고. 이 옵션은 크로스 오리진(Cross-Origin) 요청 시에도 쿠키를 포함하도록 할 수 있고, 혹은 요청 시 응답으로 쿠키를 받아 올 수 있다.

 

 

const response = await fetch(
        'http://localhost:8080/api/v1/members/login',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ email, password }),
          credentials: 'include',
        },
      );

 

Axios요청이 아닌 Fetch요청을 사용한 코드이므로 credentials: 'include'를 사용하였다.

 

단 한 줄의 코드만 추가했다고 모든 문제점이 해결이 되었다.

 

단 로그인 API 뿐만 아니라. 다른 API에도 해당 코드를 적어주어야 서버에서 쿠키를 전달받을 수 있다.


최종정리

크로스 오리진이 아닌 경우(즉, 동일 출처 요청인 경우)에는 withCredentials: true를 사용하지 않아도 쿠키가 자동으로 포함되고 받아진다. 하지만 Vite => spring서버로 요청을 보내는 경우이므로 동일출처 요청이 아니게 된다.

 

위와 같은 이유로 쿠키를 아무리 받고 보내려고 해도 기존의 방식으로는 할 수 없는 것이다.(보안 문제가 가장 크겠죠!)

 

이 경우 가장 먼저 CORS설정 확인을 해주어야 한다.

https://kingmusung.tistory.com/53

 

[연동문제] CORS로 인한 서버 연동문제(axios <=> django)

개요.Django + Axios를 이용, 로컬에서 간단한 연동 후 API테스트를 진행하려던 와중 발생함. 문제🔒 [26/Jun/2024 10:54:41] "OPTIONS /test/ HTTP/1.1" 200 163(Django 서버의 응답)분명히 Axios에 url 엔드포인트를 작

kingmusung.tistory.com

위 글은 spring boot CORS설정은 아니지만 CORS관련해서 문제해결 한 부분을 첨부해 보았다.

 

CORS설정이 완료되었다면, fetch 혹은 axios요청 시

credentials: 'include' // fetch 요청시 사용
혹은
withCredentials: true, // Axios요청 혹은 XMLHttpRequest 요청시 사용 가능

상황에 맞춰서 사용

 

위 코드를 추가해 주면 해결이 된다.