HTTP는 Client가 요청을 보내면 Server에서 응답 후 연결을 끊는 특징이 있다. 응답 후 연결을 끊음으로써 지속적으로 연결을 유지하지 않아도 된다는 장점이 있으나 서비스 제공 시 요청을 보낸 사용자를 구분해야 하는 상황이 있을 경우 누가 요청을 보냈는지 알 수가 없다.
사용자를 구분하기 위해서 쿠키 또는 세션을 사용한다.
쿠키는 요청을 보낸 사용자의 정보를 Client에 저장하는 방식이다. 사용자가 Server에 요청을 보낼 때 HTTP header에 사용자의 정보를 담아 Server에 전송하며 쿠키 정보를 보고 Server는 사용자를 판단한다.
쿠키는 문자열로 저장되어 쿠키를 이용하여 정보를 저장할 경우 문자열 파싱이 필요하다.
세션은 요청을 보낸 사용자의 정보를 Server에 저장하는 방식이다. 사용자마다 세션 ID를 부여하여 동일한 사용자인지 판단한다.
참고 사이트에서 일부 이해한 부분만 작성하였다.
쿠키는 window.document.cookie
에 저장된다.
위 이미지는 구글창에 '벨로그'를 검색했을 경우의 쿠키값이다.
javascript에서 쿠키를 저장할 때에는 다음과 같이 key=value
형태로 저장한다.
document.cookie = "key=value";
쿠키 특징은 이전에 저장한 key를 이용하여 쿠키를 다시 저장할 경우 입력되어 있는 정보가 업데이트된다.
document.cookie = "key=value2";
저장한 쿠키를 삭제하고 싶은 경우 빈값을 다시 저장하여 value를 삭제한다.
document.cookie = "key=";
현재 페이지의 쿠키 정보는 크롬 개발자 도구(F12)의 Application > Cookies
탭에서 자세하게 확인할 수 있다.
위에서 설명한대로 쿠키를 설정하면 페이지 이동 시 설정한 쿠키가 보이지 않는다. 쿠키 설정 시 옵션을 작성하지 않으면 추가한 쿠키 정보는 현재 경로
에 종속되어 있다.
쿠키의 접근 범위는 path
와 domain
옵션을 이용해 설정할 수 있다.
쿠키 설정 시 path에 저장한 경로의 하위 경로에서만 쿠키에 접근할 수 있다. path를 /path1로 설정할 경우 /path1 또는 /path1/path2 등의 하위 경로에서 쿠키를 사용할 수 있다.
현재 도메인의 모든 경로에서 사용해야하는 쿠키일 경우 path는 /
로 설정한다.
기본 path값은 현재 경로이다.
옵션은 세미콜론(;)을 이용하여 추가할 수 있다.
document.cookie = "key=value; path=/";
쿠키 설정 시 domain에 저장한 도메인에서만 쿠키에 접근할 수 있다.
document.cookie = "key=value; path=/; domain=localhost";
쿠키 설정 시 max-age에 설정한 초 만큼 쿠키가 유지된다. 설정한 초가 지날 경우 해당 쿠키는 완전 삭제된다. max-age에 0을 설정할 경우 생성되자마자 삭제된다.
document.cookie = "key=value; path=/; domain=localhost; max-age=0";
쿠키에는 최대 개수와 최대 크기가 지정되어 있다. 개수 및 크기 제한은 브라우저마다 다르다. 나는 크롬에 맞춰서 개발하기 때문에 최대 180개, 4096 bytes 미만으로 작업하였다. Application > Cookies
의 size
는 bytes 기준이므로 해당 정보를 확인하면 된다.
쿠키는 문자열로 저장되기 때문에 저장한 쿠키의 값을 조회하려면 문자열 파싱 과정이 필요하다.
쿠키가 여러개 저장되어 있는 경우 key1=value1; key2=value2; key3=value3
의 형태로 저장된다. 옵션으로 추가한 path나 domain은 보여지지 않는다.
사용자의 기록을 매 페이지마다 남겨야 해서 배열 형태로 저장한 데이터를 문자열로 변경 후 쿠키에 저장하였다. 쿠키를 사용할 때에는 다시 배열 형태로 전환하였다.
쿠키 형태
key1=['key1-value1', 'key1-value2', ...]
key2=['key2-value1', 'key2-value2', ...]
문자열 형식으로 된 쿠키를 조회한다.
function get_cookie() {
var cookie_list = document.cookie.split("; ");
// 아직 쿠키가 설정되지 않은 경우
if (cookie_list[0] == "") {
return {"key1":[], "key2": []};
}
var key1_list = [];
var key2_list = [];
var now_cookie_list = [];
for (var i = 0; i < cookie_list.length; i++) {
now_cookie_list = cookie_list[i].split("=");
if (now_cookie_list[0] == "key1") {
key1_list = JSON.parse(decodeURI(cookie_list[i].substring(cookie_list[i].indexOf("=") + 1)));
} else if (now_cookie_list[0] == "key2") {
key2_list = JSON.parse(decodeURI(cookie_list[i].substring(cookie_list[i].indexOf("=") + 1)));
}
}
return {"key1":key1_list, "key2": key2_list};
}
key1 과 key2 에 해당하는 쿠키가 없었을 경우 생성되며 있었을 경우 value1 과 value2 의 값이 수정된다.
// 쿠키를 설정 또는 수정
function set_cookie(cookie_info) {
if (chk_cookie_max_size_over(cookie_info)) {
cookie_info['key1'] = [];
cookie_info['key2'] = [];
}
var now_hostname = window.location.hostname;
if (cookie_info['key1'].length) {
document.cookie = "key1=" + encodeURI(JSON.stringify(cookie_info['key1'])) + "; path=/; domain=" + now_hostname;
document.cookie = "key2=" + encodeURI(JSON.stringify(cookie_info['key2'])) + "; path=/; domain=" + now_hostname;
} else {
document.cookie = "key1=" + encodeURI(JSON.stringify(cookie_info['key1'])) + "; path=/; domain=" + now_hostname + "; max-age=0";
document.cookie = "key2=" + encodeURI(JSON.stringify(cookie_info['key2'])) + "; path=/; domain=" + now_hostname + "; max-age=0";
}
}
function chk_cookie_max_size_over(cookie_info) {
var key1_size = ("key1" + encodeURI(JSON.stringify(cookie_info['key1']))).length;
var key2_size = ("key2" + encodeURI(JSON.stringify(cookie_info['key2']))).length;
return (key1_size > 4096 || key2_size > 4069)
}
function del_cookie() {
var cookie_info = {};
cookie_info['URL'] = [];
cookie_info['parameters'] = [];
set_cookie(cookie_info);
}
저장된 쿠키에서 마우스 오른쪽을 클릭하면 'Delete'가 있다. Delete 선택 시 직접 쿠키를 삭제할 수 있다.
혼자 삽질할 때 애용한 방법이다...