이슈
- 웹 클라이언트 키패드 샘플이 정상적으로 데이터 요청을 하던 동일한 키패드 서버에, RN 웹뷰에서 동일한 요청을 했으나 RN 웹뷰에서만 복호화 이슈가 발생함.
- 서버에서 동일한 형태의 응답값을 받는 것까지 확인한 상황.
상황 및 이슈 분석
- 서버에서 로그를 찍어봤을 때, 다른 요청과 응답 모두 정상적으로 오고가는데 복호화에 대해서만 에러 발생
- 복호화 에러 원인을 파악해 보았을 때, RSA 공개키 발급 시 부여한 세션ID와 복호화 요청을 받았을 때 세션이 일치하지 않아서 발생
- 기본적으로, 클라이언트로부터 RSA 공개키 요청/복호화 요청을 받을 때 모두, 해당 요청에 동봉된
JSESSIONID세션 쿠키가 없다면, 세션 쿠키를 생성 후 보냄.- 분명 서버에서 세션 ID 값을 받았는데, 복호화 진행 시 세션이 다르다는 건 어디선가 새로 재발급이 이루어졌다는 것이고, 그렇다는 건 서버에서 복호화 요청을 받을 때 RSA 응답에 동봉한 그 쿠키(세션ID)를 받지 못했다는 거고, 그렇다는 것은 클라이언트에서 쿠키를 동봉하지 않았다는 것이라고 유추가 가능함.
삽질
- 쿠키가 어디서 유실되는 지 당최 왜 동봉이 안되는 건지 확인하기 위해 서버사이드에서 클라이언트사이드에서 요청과 응답을 막 찍어댔는데, 이게 불가능하다는 걸 알면서도 계속했음…
- HttpOnly 쿠키는 자바스크립트로 접근이 안됨.
- 헤더의 **
Set-Cookie**는 그냥 조회 자체가 안됨 → **null**임.
- 웹뷰에서 쿠키를 받지를 못했거나, 유실이 된다라고 거의 판단이 이루어짐.
- 도대체 왜 브라우저는 쿠키를 잘 동봉해서 보내는데, 웹뷰는 동봉을 못하는 것일까?
- 자바스크립트로 확인이 어렵고, 웹뷰에서 쿠키를 저장하는 공간을 확인하는 방법을 모르니 쿠키를 받긴 받았는지, 받지도 않았는지 확인도 못함
해결
- 아주 우연히 서버에서 쿠키를
SameSite=None으로 설정하니 바로 해결됐음. SameSite는 크로스 사이트 요청에 해당 쿠키를 동봉할지 결정하는 속성- 기존에는
SameSite가 명시되지 않아Lax처럼 처리되었고, RN 웹뷰에서 키패드 서버로 직접 보내는fetch()요청에는JSESSIONID가 동봉되지 않았음. SameSite=None으로 설정하자 크로스 사이트 요청에도JSESSIONID가 다시 동봉되었고, 공개키를 발급한 세션과 복호화 요청의 세션이 동일해져 정상적으로 복호화됨.- 현재 브라우저 정책에서는 일반적으로
SameSite=None과Secure를 함께 설정해야 함.
- 기존에는
사후 분석
- 근데 왜 WebView에서만 이슈가 발생했고,
SameSite=None을 설정하지 않은 것이 웹 샘플에서는 문제가 되지 않았는가?
-
현대적인 Chromium 계열 환경에서는 쿠키에
SameSite를 명시하지 않으면 기본적으로SameSite=Lax처럼 처리됨. -
웹 키패드 샘플은 GET 요청이긴 했지만,
fetch()를 통해 RSA 공개키를 받아오고 복호화 요청을 하고 있었음.-
다만 웹 개발 환경에서는 Vite의 프록시 서버를 사용하고 있었음.
-
즉, 브라우저에서는 같은 사이트 요청으로 처리되어 쿠키가 정상적으로 전송되었던 것.
-
-
리액트 네이티브에서는 배포된 웹사이트를 WebView로 띄우고 있었고, 배포 환경에서는 프록시 없이 키패드 서버 URL을 직접 호출하고 있었음.
- 배포 웹사이트와 키패드 서버가 서로 다른 Site로 평가되면서 크로스 사이트
fetch()요청이 되었고,SameSite=Lax로 처리된JSESSIONID가 복호화 요청에 동봉되지 않았음.
- 배포 웹사이트와 키패드 서버가 서로 다른 Site로 평가되면서 크로스 사이트
-
따라서 배포 환경에서도 동일한 프록시 경로를 유지하거나, 키패드 서버의 세션 쿠키를 크로스 사이트 요청에 맞게
SameSite=None; Secure로 설정해야 했음.- 직접 호출 구조에서는 이와 별도로
fetch의 credentials와 서버의 credentialed CORS 조건도 충족되어야 함. - 당시에는 세션 전달을 막고 있던 마지막 조건이
SameSite였기 때문에 서버의 쿠키 설정을 수정하는 방식을 선택함.
- 직접 호출 구조에서는 이와 별도로
