개인 포트폴리오용 서버를 Docker + Nginx + Vue + SpringBoot 환경으로 배포를 시도하고 있는 중이다.
수많은 문제점들과 SSL 인증서까지 다 적용에 간신히 성공했다. 수많은 트러블 중 만났던 하나의 트러블에 대한 해결방법을 남긴다.

 

SSL 인증서를 발급 받은 이후 docker nginx 에서 도메인으로 들어오는 http(80포트) 에 대해 https(443포트)로 리다이렉트 하도록 설정해 두었다. Frontend -> Backend API 요청은 문제없이 리다이렉트 되어서 해결되는 듯 하였지만 스웨거 페이지가 문제였다.

 

어째서인지 Swagger UI 에서의 요청은 Spring 에 닿지조차 못하였다. 그러던 중 요청시 https 페이지임에도 불구하고 curl 명령어가 http로 뜨는것을 확인했다. Swagger UI 에서는 curl 명령어로 실행해서 요청을 호출하는 것 같았다. 해당 명령어를 실행한 결과 Spring이 아니라 nginx 에서 Redirect 했다는 내용이 나오는 것을 확인했다.

 

아마 Swagger에서의 요청은 리다이렉트된 Spring 까지 도달하지 못하였던듯 하다. 관련해서 찾아보다 설정으로 처리 하는 방법을 발견하여 적용하였고 해결하였다.

 

server.forward-headers-strategy=framework

 

위와같은 설정을 application.properties로 추가하니 요청이 정상적으로 도달하였다.
해당 설정을 넣기전에는 스웨거의 curl 명령어가 https 라는 헤더정보가 누락된었던 듯 하며, 해당 설정 이후 정보들이 제대로 전달되어, swagger 의 curl 요청이 정상적으로 변경된듯 하다

이전글 - 개발을 위해 Local, Dev Server WAS 환경 분리하기 1 - Intellij 환경 변수 이용하기 :: 꿀잠 (tistory.com)

 

개발을 위해 Local, Dev Server WAS 환경 분리하기 1 - Intellij 환경 변수 이용하기

오늘은 개발시 프론트엔드(WEB) 프로젝트와 백엔드(WAS) 프로젝트로 분리되어 있을 시 LOCAL WAS 또는 배포되어진 WAS로 환경을 분리한 경험을 기록하고자 한다. 현재 진행중인 프로젝

ygs3004.tistory.com

 

 

WAS 환경을 분리하기 위해 axios 의 base url 을 분리하였고, 문제는 해결되어진 것으로 보았다. 그러나 그 이후 더 큰 문제가 발생하였다. 개발 WAS 에서 Session ID 가 요청마다 새로 생기는 문제였다. 우리의 로그인 방식이 세션 방식이었기에 이 문제는 크게 작용하였다.

 

로컬 WAS 환경에선 문제 없었으나 개발 WAS 에선 로그인 이후에 바로 다음 요청시 세션이 초기화 되어 로그인 인증을 할 수 없는 것이었다.

 

이것은 CSRF 방지를 위한 브라우저의 보안 정책 때문이었다. 세션 ID를 담은 쿠키를 보내려면 적절한 SameSite 정책이 포함되어야 하는 것이었다. Dev WAS 와 Local WEB으로 분리된 프로젝트 환경이기에 기본적으로 같은 사이트(SameSite)가 아닌 상황이었고, 서버는 SameSite 가 아닌 WEB 프로젝트의 쿠키를 폐기하고 새로 생성하였던 것이다.

아래와 같이 Spring Boot 의 CookieSerializer Bean을 새로 등록하는 방식으로 SameSite 정책을 None으로 변경해주었다.

 

@Bean
public CookieSerializer cookieSerializer() throws MalformedURLException {
    DefaultCookieSerializer serializer = new DefaultCookieSerializer();
    serializer.setSameSite("None");
    serializer.setUseSecureCookie(true); // None 일 경우 필수
    return serializer;
}

 

위와 같이 None 설정을 하여 진행하였지만 이후에 추가적인 문제가 생겼다. 바로 Secure 옵션을 반드시 주어야 한다는 점이다. 프로젝트에 HTTPS를 적용하여야 했다. Local 환경에 SSL 인증서를 설치하는 방법도 있지만 개발 환경에서 serve 명령어를 변경하여 간단히 해결하는 방법도 있다. package.json 에서 npm run serve 명령어를 아래와 같이 옵션을 주는 형태로 해결하였다.

 

 "serve": "vue-cli-service serve --https true",
 "serve-local": "vue-cli-service serve",

 

Dev Server WAS 환경을 바라 볼 때는 npm run serve 명령어를 사용하고, Local WAS 를 바라볼 때는 npm run serve-local를 사용하면 된다. Local 에서는 SameSite 인 상황이기에 쿠키의 새로운 생성을 걱정하지 않아도 되었기 때문이다.

분리 방법을 요약 하자면 아래와 같다.

  1. 환경 변수를 이용한 axios base url 분리
  2. Local Web -> Server Was 환경에서 Session 이 초기화 되면 안되는 환경일 경우 SameSite None, SecureCookie 설정
  3. Local Web Https 적용(로컬 SSL 인증서 설치 또는 실행 명령어로 해결)

이로써 로컬 및 서버 WAS 인지에 따른 개발환경 분리를 완료할 수 있었다.

 


추가내용

CookieSerializer Bean 을 새로 등록하는 방법 외에도 방법이 있어 변경하여 적용후 남긴다.

개발 환경에서만 필요한 옵션이었기에 개발서버 기준application.properties 로 분리하였다.

server.servlet.session.cookie.same-site=none
server.servlet.session.cookie.secure=true

+ Recent posts