ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Session과 SameSite
    spring/session 2021. 3. 24. 17:15

    배경

    프로젝트를 진행하다보면 여러가지 문제를 만난다. 그 중 비교적 쉽게 해결하는 문제가 있는 반면 상당히 오랜 시간을 들여 해결하는 문제가 있다. 재밌는 건 아무리 어려운 문제여도 문제를 정확하게 정의하고 원인을 파악한다면 해결하는 건 쉽다는 점이다. 중요한 건 지금 일어난 문제가 어떤 문제이고 원인을 파악하는 것이다.

     

    SameSite이슈를 해결하기 위해 걸린 시간은 1시간 정도로 매우 짧았지만 지금 발생하는 버그의 원인이SameSite때문이란 걸 확인하는 데에는 3~4시간 정도 걸린 매우 힘겨운 문제였다. 

     

    진행하는 프로젝트는 프런트와 백 서버를 분리한 프로젝트다. 프런트에서 유저정보와 함께 백서버로 로그인 인증 요청을 하면 백서버에서 검증과정 결과를 프론트로 다시 전달한다. 이때 stateless한 http의 요청으로 유저의 정보를 구분하기 위해 session cookie 방식을 사용했다. 로컬에서 테스트할 때는 요청에 대한 쿠키를 브라우저가 잘 관리했고 문제가 없었다. 반면, 실제 물리서버에 빌드파일을 배포하고 테스트를 진행했을 때 브라우저가 쿠키를 저장하지 못해 인증된 사용자와 관련된 작업을 처리하지 못하는 버그를 만나게 되었다.

     

     

     

    테스트 과정

    spring security는 사용자 인증 성공여부와 관계없이 로그인을 시도하면 JSESSION라는 이름으로 쿠키를 발급한다. (spring security의 formLogin사용, axios에서 요청URL을 시큐리티에서 로그인처리 URL로 지정해야 함)

    이 쿠키로 사용자를 식별하고 쿠키를 소유한 사용자의 권한을 세션에 저장해 자원 허용범위를 결정하는 방식이다. 위에서처럼 로컬에서 진행한 테스트는 쿠키를 브라우저가 잘 저장하고 있다. 여기서 프런트 서버를 로컬환경이 아닌 S3에 업로드하고 동일한 테스트를 진행해 쿠키가 저장되는지 확인해보자.

    동일한 코드의 동일한 버튼을 눌렀고 다른 결과가 나왔다. S3에서 요청했을 때는 쿠키를 저장하지 못한 것이다! 여기서부터 고난의 과정이었는데 백엔드서버의 문제인지 프런트엔드서버의 문제인지 도저히 감이 오질 않았다. 디버깅 작업을 하던 중 브라우저 개발자 도구에서 단서를 얻었다.

     

    Response Headers에 쿠키값이 있는 걸 보면 서버는 분명 쿠키를 set해서 보낸 것이다. 단지 브라우저가 이 쿠키를 저장하지 않은 거고 귀여운 경고문구가 나타난걸 보니 이걸 분석해봐야지 했다.

     

    "this set-cookie didn't specify a samesite attribute and was default to samesite=lax and was blocked..."

    내용을 보면 SameSite 속성이 lax로 되어 있어서 서로 다른 site끼리는 쿠키값을 저장하지 않는다는 내용이었다. SameSite는 무엇이며, lax는 무엇일까... CORS해결하면 된 거 아니냐...

     

    SameSite

    samesite는 쿠키의 설정이고 대부분의 브라우저가 lax속성을 기본으로 설정하고 있다. 크롬도 마찬가지로 lax속성을 기본으로 하고, 이는 cross-site 끼리의 통신은 특별한 경우를 제외하곤 쿠키를 따로 관리하지 않음을 의미한다.

     

     

    SameSite 관련 쿠키 저장 이슈 해결하기

    우선 samesite 설정 자체를 lax에서 none으로 바꾸는 방법이 있다. 하지만 이 방법은 http요청을 반드시https로 전환해주어야 하고 현재 프로젝트 성격과는 맞지 않으니 패스하자. 다음으로 백엔드에서 쿠키를 저장할 때 domain을 지정하는 방법이다. 

    application.yml에 위와 같이 쿠키관련 설정을 추가한다. domain에 본인이 구매한 도메인을 작성해주면 되는데 테스트용 amazonaws.com은 public suffix로 간주되어 동작하지 않았다. 즉, com co.kr과 같은 공공 도메인은 domain영역에 set해도 동작하지 않도록 브라우저가 구성되어 있다. 여하튼 구매한 도메인으로 설정한 뒤 실행하면 쿠키가 잘 저장되는 걸 확인할 수 있다.

    'spring > session' 카테고리의 다른 글

    spring session 아키텍처  (0) 2021.02.22

    댓글

Designed by Tistory.