💡 로컬스토리지는 웹 스토리지 객체로 브라우저 내에 { key : value } 형태로 오리진에 종속되어 저장되는 데이터
하나의 값
만 저장됩니다.5MB
입니다.localStorage.setItem(key, value); // 설정
localStorage.getItem(key); // key에 해당하는 value 가져오기
localStorage.removeItem(key); // 제거
localStorage.clear() // 전체 제거
origin
443
이기 때문에 ⇒ 생략 가능80
⇒ 생략 가능💡 컨텐츠가 달라도 오리진만 같으면 로컬스토리지 공유 가능
header-authorization
헤더를 이용해서 서버에 전달을 함<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,
initial-scale=1.0">
<title>Document</title>
<style>
/* CSS */
.button-62 {
background: linear-gradient(to bottom right, #EF4765,
#FF9A5A);
border: 0;
border-radius: 12px;
color: #FFFFFF;
cursor: pointer;
display: inline-block;
font-family: -apple-system, system-ui, "Segoe UI",
Roboto, Helvetica, Arial, sans-serif;
font-size: 16px;
font-weight: 500;
line-height: 2.5;
outline: transparent;
padding: 0 1rem;
text-align: center;
text-decoration: none;
transition: box-shadow .2s ease-in-out;
user-select: none;
-webkit-user-select: none;
touch-action: manipulation;
white-space: nowrap;
}
.button-62:not([disabled]):focus {
box-shadow: 0 0 .25rem rgba(0, 0, 0, 0.5), -.125rem -.125rem 1rem rgba(239, 71, 101, 0.5), .125rem .125rem 1rem rgba(255, 154, 90, 0.5);
}
.button-62:not([disabled]):hover {
box-shadow: 0 0 .25rem rgba(0, 0, 0, 0.5), -.125rem -.125rem 1rem rgba(239, 71, 101, 0.5), .125rem .125rem 1rem rgba(255, 154, 90, 0.5);
}
#field {
font-size: 27px;
}
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0 auto;
height: 100vh;
}
</style>
</head>
<body>
<div>
<input type="text" id="field" />
<input type="button" class="button-62" value="검색" 89 id="save" />
<input type="button" class="button-62" value="조회" id="read" />
<input type="button" class="button-62" value="삭제" id="clear" />
</div>
</body>
<script>
window.onload = async () => {
const field = document.getElementById("field"),
save = document.getElementById("save"),
read = document.getElementById("read"),
clear = document.getElementById("clear")
save.addEventListener("click", e =>
localStorage.setItem("입력값", field.value))
read.addEventListener("click", e =>
alert(window.localStorage["입력값"]))
clear.addEventListener("click", e => {
window.localStorage.clear()
field.value = ""
})
if (window.localStorage["입력값"]) {
field.value = window.localStorage["입력값"]
}
}
</script>
</html>
세션 스토리지(session Storage)는 로컬 스토리지와 매우 유사합니다.
💡 세션 스토리지는 웹 스토리지 객체로 브라우저 내에 { key : value } 형태로 오리진에 종속되어 저장되는 데이터. (오리진이 같은 브라우저 내에서 공유 됩니다.)탭을 닫으면
데이터는 만료 됩니다.sessionStorage.setItem(key, value); // 설정
sessionStorage.getItem(key); // 탐색
sessionStorage.removeItem(key); // 제거
sessionStorage.clear() // 전체 제거
💡 브라우저에 저장된 데이터 조각
응답헤더로 Set-Cookie
로 어떤 값을 설정해서 쿠키를 보내면 그 때 부터 클라이언트에서 요청헤더 Cookie
에 설정되어 자동으로 서버에 전달되게 되고 브라우저에도 저장되게 됩니다.axios.get(url, {
headers: {
Cookie: "cookie1=value; cookie2=value;
cookie3=value;"
}
}).then
세션쿠키 (Session Cookie) | 영구쿠기 (Persistent Cookie) |
---|---|
- 브라우저가 열려 있는 동안 유효함 | - 하드디스크에 유효기간 동안 저장됨 |
- 서버를 이용하는 동안 사용자 정보를 유지하기 위해 사용됨 | - 사이트 재방문 시 사용자 정보를 기억하기 위해 사용됨 |
세션 | 세션 쿠키 | 세션 스토리지 | |
---|---|---|---|
위치 | 서버 측에서 관리되는 상태 저장 방법 | 클라이언트 측에서 관리되는 쿠키의 일종 | 클라이언트 측 웹 스토리지 메커니즘 |
동작 방식 | 서버는 각 유저마다 고유한 세션을 생성하고, 클라이언트에 대한 세션 ID를 부여합니다. 이 세션 ID는 일반적으로 쿠키를 통해 클라이언트에게 전달됩니다. | 보통 세션 ID와 같은 정보가 쿠키에 저장되어, 클라이언트가 해당 ID를 서버에 전달하면 서버는 해당 세션과 관련된 데이터를 찾아 사용 | 클라이언트의 브라우저 내부에 데이터를 저장합니다. 같은 도메인과 프로토콜을 가진 페이지 간에 데이터를 공유 |
수명 | 일반적으로 유저의 활동 동안 유지되며, 서버가 일정 기간 동안 세션 데이터를 보관할 수 있습니다. | 브라우저 세션이 끝날 때(브라우저 종료 시) 쿠키가 삭제 | 해당 페이지의 세션이 유지되는 동안 데이터가 유지 |
보안 | 주로 서버 측에서 데이터를 관리하므로 보안 측면에서 더 안전합니다. 중요한 정보나 인증 데이터를 저장 | 서버 측 세션보다는 보안적으로 약간 취약 (클라이언트가 직접 관리) | 서버 측 세션보다는 약간 취약합니다. 중요한 정보를 저장하는 데는 적합하지 않음 |
웹 사이트의 속도 저하 문제
도 일으킬 수 있기 때문이다.지워지고 조작되고 가로채이더라도 문제 없을 정보만 쿠키로 사용되고
중요한 보안과 관련된 정보 등은 세션을 통해 서버에서 다뤄지는 것이다.
빈번한 새로고침이나 페이지 이동을 감지
하고 세션을 보호하기 위해 세션을 만료시키는 경우도 있을 수 있습니다.˙ 자바스크립트를 이용하여 document.cookie 값을 탈취할 수 있음
˙ 네트워크를 통해 전송되는 쿠키값을 암호화하지 않고 전송하는 경우 네트워크 스니핑 공격을 통해 쿠키값을 탈취할 수 있음
˙ 영속성 쿠키는 하드디스크에 저장되며, 간단한 방법으로 접근 가능하기 때문에 공용PC 사용시 PC에 저장된 사용자 정보가 유출될 수 있음
Set-Cookie: <cookie-name>=<cookie-value>
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
Set-Cookie: <cookie-name>=<cookie-value>; SameSite=Strict
이 사양을 현재는 무시
합니다.const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
// 쿠키 설정 Secure 옵션으로
res.setHeader('Set-Cookie', ['kundol = amumu; httponly',
'loltier = master; Secure']);
res.end('큰돌, 그는 신인가?!\n');
});
server.listen(port, hostname, () => {
console.log(Server running at < http: //$>{hostname}:${port}/);
});
cookie에 세션ID를 담을 때 이 세션ID기반으로 클라이언트의 개인정보를 유추할 수 없게 해야 합니다.
자바스크립트로는 파악할 수 없게 http only 옵션을 걸어야 합니다.
일정시간의 세션 타임아웃 걸어야 합니다.
업비트의 세션타임아웃으로 공격자의 접근을 차단할 수 있다.
실수로 로그인을 하고 떠나더라도 자동으로 로그아웃 되기 때문에 안전
사용자의 데이터 간접수집
에 해당하며 거기에 해당하는 KISA 지침을 준수해야 하기 때문입니다.정보보호 및 개인정보보호 관리체계(ISMS-P) 인증기준(KISA) 2019.01
3.1.5 간접수집 보호조치
정보주체(이용자) 이외로부터 개인정보를 수집하거나 제공받는 경우에는 업무에 필요한 최소한의 개인정보만 수집 ․ 이용하여야 하고 법령에 근거하거나 정보주체(이용자)의요구가 있으면 개인정보의 수집 출처, 처리목적, 처리정지의 요구권리를 알려야 한다.
서비스 계약 이행을 위해 필요한 경우로서 사업자가 서비스 제공과정에서 자동수집장치 등에
의해 수집 ․ 생성되는 개인정보(통화기록, 접속로그, 결제기록, 이용내역 등)에 대해서도,
해당 서비스의 계약 이행 및 제공을 위해 필요한 최소한의 개인정보만을 수집하여야 한다.
▶ 다만, 서비스 제공 계약 이행과는 무관한 목적으로 이용하기 위해 수집하는 경우에는 선택 동의 항목으로 분류하여 별도의 사전 동의를 받아야 함 (예를 들어, 쿠키를 통해 수집하는 행태정보를 분석하여 개인별 맞춤형 광고에 활용하는 경우 등)
쿠키 | 로컬 스토리지 | 세션 스토리지 | |
---|---|---|---|
최대저장용량 | 4KB | 5MB | 5MB |
브라우저 허용 | HTML4 + 5 | HTML 5 | HTML 5 |
접근 범위 | 창 | 창 | 탭 |
만료 기한 | 수동으로 설정 | 영구적 | 탭 닫으면 소멸 |
설정할 수 있는 주체 | 클라이언트 + 서버 | 클라이언트 | 클라이언트 |
요청과 함께 서버에 자동전송 유무 | O | X | X |
출처 : 인프런 CS 지식의 정석