728x90
반응형
쿠키와 document.cookie
쿠키
- 브라우저에 저장되는 작은 크기의 문자열 →RFC 6265 명세에서 정의한 HTTP 프로토콜의 일부.
- 주로 웹 서버에 의해 만들어짐.
- 서버가 HTTP 응답 헤더의 Set-Cookie에 내용을 넣어 전달.
- 브라우저는 이 내용을 자체적으로 브라우저에 저장 = 이것이 쿠키! - 브라우저는 사용자가 쿠키를 생성한 동일 서버(사이트)에 접속할 때마다, 쿠키의 내용을 Cookie 요청 헤더에 넣어서 함께 전달.
- 클라이언트 식별과 같은 인증에서 주로 사용됨.
- 사용자가 로그인하면, 서버는 HTTP 응답 헤더의 Set-Cookie에 담긴 “세션 식별자(session identifier)” 정보를 사용해 쿠키를 설정.
- 사용자가 동일 도메인에 접속하려고 하면, 브라우저는 HTTP Cookie 헤더에 인증 정보가 담긴 고윳값(세션 식별자)을 함께 실어 서버에 요청 보냄.
- 서버는 브라우저가 보낸 요청 헤더의 세션 식별자를 읽어 사용자를 식별.
- document.cookie 프로퍼티를 이용해 브라우저에서도 쿠키에 접근 가능.
쿠키 읽기
alert( document.cookie ); // cookie1=value1; cookie2=value2;...
- document.cookie → name=value 쌍으로 구성됨. 이때 각 쌍은 ; 로 구분하며, 쌍 하나는 하나의 독립된 쿠기를 나타냄.
- ; 을 기준으로 document.cookie의 값을 분리하면, 원하는 쿠키를 찾을 수 있음.
쿠키 쓰기
- document.cookie에 직접 값을 쓸 수 O.
- 이때 cookie는 데이터 프로퍼티가 아닌, 접근자(accessor) 프로퍼티!
- document.cookie에 값을 할당하면, 브라우저는 이 값을 받아 해당 쿠키를 갱신. 이때, 다른 쿠키의 값은 변경되지 않음.
document.cookie = "user=John"; // 이름이 'user'인 쿠키의 값만 갱신함
alert(document.cookie); // 모든 쿠키 보여주기
// -> 명시된 쿠키인 user의 값만 변경된 모습!
- 쿠키의 name과 value에 특별한 제약은 존재X.
- 하지만 형식의 유효성을 일관성 있게 유지하기 위해,
반드시 내장 함수 encodeURIComponent를 사용해 이름과 값을 이스케이프 처리해 줘야 함!
- 하지만 형식의 유효성을 일관성 있게 유지하기 위해,
// 특수 값(공백)은 인코딩 처리해 줘야 합니다.
let name = "my name";
let value = "John Smith"
// 인코딩 처리를 해, 쿠키를 my%20name=John%20Smith 로 변경하였습니다.
document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
alert(document.cookie); // ...; my%20name=John%20Smith
- 제약 사항
- encodeURIComponent로 인코딩한 이후의 name=value 쌍은 4KB를 넘을 수 없음.
(이 용량을 넘는 정보는 쿠키에 저장할 수 없다) - 도메인 하나당 저장할 수 있는 쿠키의 개수는 20여 개 정도로 한정!
(개수는 브라우저에 따라 조금씩 다름)
- encodeURIComponent로 인코딩한 이후의 name=value 쌍은 4KB를 넘을 수 없음.
옵션
- 쿠키에는 몇 가지 옵션이 존재 → 몇몇 옵션은 아주 중요! (꼭 지정해줘야 함)
- 옵션은 key=value 뒤에 나열하고 ; 로 구분.
document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"
1. Path
path=/mypath
- URL path의 접두사.
- 해당 경로 또는 해당 경로의 하위 경로에 있는 페이지만 쿠키에 접근 가능.
- 절대 경로여야 함 - 미 지정 시 기본값은 현재 경로!
- 특별한 경우가 아니라면, path 옵션을 path=/ 과 같이 루트로 설정해, 모든 페이지에서 쿠키에 접근할 수 있도록 해줌.
2. domain
domain=site.com
- 쿠키에 접근 가능한 도메인을 지정.
- 제약 존재 - 아무 도메인이나 지정할 수 있는 것은 X
- domain 옵션에 아무 값도 넣지 않았을 경우
- 쿠키를 설정한 도메인에서만 쿠키에 접근 가능
- 서브 도메인에서도 쿠키에 접근 불가능!!! - 서브 도메인이나 다른 도메인에서 쿠키에 접속할 방법은... 존재하지 않음.
but domain 옵션을 명시적으로 설정함으로써 가능해짐.
// site.com에서 쿠키를 설정함
document.cookie = "user=John"
// site.com의 서브도메인인 forum.site.com에서 user 쿠키에 접근하려 함
alert(document.cookie); // 찾을 수 없음
// site.com에서
// 서브 도메인(*.site.com) 어디서든 쿠키에 접속하게 설정할 수 있습니다.
document.cookie = "user=John; domain=site.com"
// 이렇게 설정하면
// forum.site.com와 같은 서브도메인에서도 쿠키 정보를 얻을 수 있습니다.
alert(document.cookie); // user=John 쿠키를 확인할 수 있습니다.
3. expires와 max-age
- expires(유효 일자)나 max-age(만료 기간) 옵션이 지정되어있지 않으면, 브라우저가 닫힐 때 쿠키도 함께 삭제됨.
= 세션 쿠키(session cookie) - expires 나 max-age 옵션을 설정하면 → 브라우저를 닫아도 쿠키가 삭제되지 않음!
- expires
- 브라우저는 설정된 유효 일자까지 쿠키를 유지하다가, 해당 일자에 도달하면 쿠키를 자동으로 삭제.
- 반드시 GMT(Greenwich Mean Time) 포맷으로 설정 (date.toUTCString 사용해 변환 가능)
- 과거로 지정 시 쿠키는 바로 삭제됨.
// 지금으로부터 하루 후
let date = new Date(Date.now() + 86400e3);
date = date.toUTCString();
document.cookie = "user=John; expires=" + date;
- max-age
- expires 옵션의 대안 → 쿠키 만료 기간을 설정할 수 있도록 해줌.
- 현재부터 설정하고자 하는 만료일시까지의 시간을 초로 환산한 값을 설정.
- 0이나 음수값 설정 시 쿠키는 바로 삭제됨.
// 1시간 뒤에 쿠키가 삭제됩니다.
document.cookie = "user=John; max-age=3600";
// 만료 기간을 0으로 지정하여 쿠키를 바로 삭제함
document.cookie = "user=John; max-age=0";
4. secure
secure
- HTTPS로 통신하는 경우에만 쿠키가 전송됨.
- secure 옵션이 없을 경우 → http://site.com에서 설정(생성)한 쿠키를 https://site.com에서 읽을 수 있음 (반대도 가능)
- 암호화되지 않은 HTTP 연결을 통해 전달되는 걸 원치 않을 경우 해당 옵션 사용.
// (https:// 로 통신하고 있다고 가정 중)
// 설정한 쿠키는 HTTPS 통신시에만 접근할 수 있음
document.cookie = "user=John; secure";
5. samesite
- 크로스 사이트 요청 위조(cross-site request forgery, XSRF) 공격을 막기 위해 만들어진 옵션.
- “XSRF 보호 토큰” 없이도 (이론상으로) 크로스 사이트 요청 위조를 막을 수 있음.
6. httpOnly
- 웹서버에서 Set-Cookie 헤더를 이용해 쿠키를 설정할 때 지정 가능.
- 클라이언트 측 스크립트(JS와 같은)가 쿠키를 사용할 수 없게 함.
- document.cookie를 통해 쿠키를 볼 수도 없고 조작할 수도 없음!
- 해커가 악의적인 JS 코드를 페이지에 삽입하고, 사용자가 그 페이지에 접속하기를 기다리는 방식의 공격을 예방할 때 사용.
유용한 쿠키 함수
- getCookie(name)
- 주어진 name의 쿠키를 반환
// 주어진 이름의 쿠키를 반환하는데,
// 조건에 맞는 쿠키가 없다면 undefined를 반환합니다.
function getCookie(name) {
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
return matches ? decodeURIComponent(matches[1]) : undefined;
// 쿠키값은 인코딩되어있는 상태이기 때문에 getCookie는
// 내장 함수인 decodeURIComponent를 이용해 쿠키값을 디코딩.
}
- setCookie(name, value, options)
- 현재 경로(path=/)를 기본으로, 주어진 name과 value를 가진 쿠키를 설정
function setCookie(name, value, options = {}) {
options = {
path: '/',
// 필요한 경우, 옵션 기본값을 설정할 수도 있습니다.
...options
};
if (options.expires instanceof Date) {
options.expires = options.expires.toUTCString();
}
let updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);
for (let optionKey in options) {
updatedCookie += "; " + optionKey;
let optionValue = options[optionKey];
if (optionValue !== true) {
updatedCookie += "=" + optionValue;
}
}
document.cookie = updatedCookie;
}
// Example of use:
setCookie('user', 'John', {secure: true, 'max-age': 3600});
- deleteCookie(name)
- 만료 기간을 음수로 설정해, 쿠키를 삭제.
function deleteCookie(name) {
setCookie(name, "", {
'max-age': -1
})
}
서드 파티 쿠키
- 사용자가 방문 중인 도메인이 아닌, 다른 도메인에서 설정한 쿠키.
- 브라우저에는 이러한 쿠키를 비활성화할 수 있는 기능 존재 → 사용 시 추적을 막을 수 있음.
- Safari는 서드파티 쿠키를 전면적으로 허용하지 않음.
- Firefox는 서드 파티 도메인 블랙리스트를 만들어, 리스트에 오른 도메인의 서드 파티 쿠키를 차단.
GDPR
- 사용자 개인 정보 보호를 강제하는 EU 법령.
- 쿠키를 추적하는 경우 사용자로부터 명시적인 허가를 얻어야 한다는 것이 이 법령의 중요 요건 중 하나!
- 사용자 추적 및 식별에 관한 내용을 담고 있음 (단순히 정보 저장 용도로 사용 시 강제 사항을 지킬 필요는 X)
- 인증된 사용자에 대해서만 추적 쿠키를 설정하려는 경우
가입 양식에 “개인 정보 취급 방침 동의” 같은 확인란을 만들고, 사용자가 이에 동의할 경우에만 추적 쿠키를 설정합니다. - 모든 사용자를 대상으로 추적 쿠키를 설정하려는 경우
최초 방문자에게 쿠키설정에 대한 동의를 요구하는 "작은 창"을 보여주고, 사용자가 이에 동의한 경우에만 콘텐츠를 표시하고, 추적 쿠키를 설정합니다. 새로운 방문자는 이런 절차가 번거롭다고 생각할 수 있습니다. 콘텐츠를 가리면서 "무조건 클릭해야 하는 창"을 그 누구도 달가워하지 않죠. 하지만 GDPR을 준수하려면 이 창이 반드시 있어야 합니다.
- 인증된 사용자에 대해서만 추적 쿠키를 설정하려는 경우
728x90
반응형
'source-code > FrontEnd' 카테고리의 다른 글
webpack - settings (0) | 2023.08.17 |
---|---|
TDD기반 TODO 애플리케이션 (0) | 2023.08.17 |
Atomic Design (0) | 2023.08.17 |
webpack - loader, optimization (0) | 2023.08.17 |
next input auto focus를 통한 UX 개선 (0) | 2023.08.17 |