쿠키는 헤더 영역을 통해서 송수신 된다. 서버에서 응답 headers의 Set-Cookie라는 key에 value로 String을 넘겨주면 쿠키이다.
쿠키 옵션
서버와 클라이언트가 쿠키를 주고받기 위해선 시스템 구성에 따라 옵션들이 필요하다. 예시를 보자.
Response Headers에 Set-Cookie를 보면 Authorization 이란 키값에 토큰이 들어있고 세미클론으로 구분되어 옵션들이 넘어왔다.
유효 기간
- Max-Age : 쿠키의 유효 시간을 초 단위로 설정한다.
- Expires : 쿠키가 유효한 날짜를 지정할 수 있다.
유효 기간 옵션에 따라
- 세션 쿠키( Session Cookie ) : Max-Aag, Expires 옵션이 없는 쿠키이다. 브라우저를 종료하면 삭제된다.
- 영속성 쿠키( Persistent Cookie ) : Max-Aag, Expires 옵션이 있는 쿠키이다. 종료와 무관하게 유효 시간까지 삭제되지 않는다.
Secure
- true면 HTTPS 프로토콜을 사용해야만 쿠키가 전송된다. 기본값은 false이다.
SamSite
- None : 모든 메소드 요청이 가능하다
단, None이면서 Secure true가 아니라면 Secure이 필요하다는 경고와 함께 Set-Cookie가 동작하지 않는다.
Set-Cookie가 동작한다 = 자동으로 브라우저 쿠키 저장소에 쿠키가 잘 저장된다. - Lax : 교차 출처 요청이라면 GET 메소드 요청에 대해서만 쿠키 전송이 가능하다.
- Strict : 교차 출처 요청이라면 쿠키 전송이 불가하다.
출처란 호스트 + 포트를 의미한다. 자세한 내용은 아래 글을 확인
HttpOnly
- true : 클라이언트에서 DOM을 이용해 쿠키에 접근하는 것을 막아준다. 기본값은 false이다.
Path
- 설정된 경로를 포함하는 하위 요청에만 쿠키를 서버에 전송한다. 즉 설정 경로는 서버에 대해 말한다.
기본값은 "/" 로 모든 요청에 쿠키를 같이 전송한다.
ex) "/api/post" 라면 /api/user 요청에는 쿠키를 전송하지 않는다.
Domain
가장 어려운 부분같다.
1. 서버에서 클라이언트로
서버(배포, https), 클라이언트(로컬) 구성에서 서버가 클라이언트에 sameSite와 secure을 만족시키며 쿠키를 넘겨도 클라이언트는 받을 수 없다. 서버가 응답한 쿠키의 도메인은 설정이 없다면 기본값으로 서버 도메인이고 브라우저에서 쿠키를 다룰 수 있는 것은 자신의 도메인만 가능하다. 즉 서버( cornpip.com )에서 클라이언트( cornpip.store )로 cornpip.com이란 도메인(기본)을 넘겨주어도 cornpip.store는 다룰 수 없다. 쿠키가 사라진 건 아니다. 실제로 브라우저에서 cornpip.com ( 띄우는게 없어서 응답없어도 )으로 가서 쿠키저장소를 확인해보면 쿠키가 들어온 것을 확인할 수 있다.
그럼 도메인을 localhost로 맞추면 되지않을까. 쿠키 도메인을 localhost로 하면 경고와 함께 저장소에 저장되지 않는다. localhost는 도메인이 아니여서? 그런 것 같다.
2. 클라이언트에서 서버로
즉 도메인이 다르면 일단 Set-Cookie로 값을 넘겨줄 수 없었다. 응답 쿠키에 도메인을 맞춰줘도 클라이언트에서 다룰 수 없기 때문이다. 그래서 서버에서 클라이언트는 헤더로 넘기고 클라이언트에서 쿠키 저장소에 직접 옮겼다.
이 상황에서 클라이언트가 withCredential true로 설정하고 요청을 할 때 저장소에 쿠키를 전송하지 않는다.
클라이언트에서 쿠키를 set하면 기본 값으로 클라이언트 도메인이고 서버 도메인과 달라서 브라우저가 전송하지 않는 걸까?
그럼 header에 토큰 값을 클라이언트에서 Cookie에 직접 넣는 과정에서 서버 도메인으로 설정하고 cookies.set()을 해보자. 결과는 도메인을 서버로 설정한 쿠키는 cookies.get()이 null인것을 확인할 수 있다. 아까 1 에서 마주한 문제다. 브라우저는 자기 도메인의 쿠키만 다룰 수 있다. set을 자신이 아닌 다른 도메인으로 설정한 쿠키는 다룰 수 없는 쿠키가 된 것이다.
그래서 결국 서버(배포, https), 클라이언트(로컬)에선
- 서버에선 Set-Cookie를 쓸 수 없다.
- domain이 localhost일 순 없다. - 클라이언트가 Credential이 허용된 상태에서 요청을 보내도 Cookie가 넘어가지 않는다.
- 도메인이 일치하기 않기 때문이라 생각한다.
확인하고 싶은 부분들
velog를 보면 다른 도메인의 쿠키도 저장소에 들어가 있는 것을 볼 수 있다. ( 도메인 이름들이 매우 믿음직한 것들이긴 하지만 ) 위의 결과는 domain 옵션을 사용해 교차 출처의 쿠키 저장이 가능하다고 생각하게 한다.
1의 문제에 대해선
서버(배포), 클라이언트(배포), 다른 도메인인 상황에서 서버가 쿠키 도메인을 클라이언트로 맞추면 잘 넘어갈까? ( localhost는 안되므로 ) 둘 중 하나가 http여도 생각한대로 동작할까?
2의 문제에 대해선
velog 글에서 쿠키 저장소를 보면 다른 도메인의 쿠키를 확인할 수 있는데 클라이언트가 조작할 수 있는 영역일까?
'Web' 카테고리의 다른 글
HTTP 메서드 GET/POST 차이 (0) | 2023.09.06 |
---|---|
OAuth2 를 알아보자 (0) | 2023.07.25 |
CORS (0) | 2023.07.20 |