
cookie: 클라이언트 → 서버)set-cookie: 서버 → 클라이언트)npm init -y
npm install express cors cookie-parser
index.html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div>
<button id="set-cookie">쿠키 추가</button>
<button id="delete-cookie">쿠키 삭제</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="cookie.js"></script>
</body>
</html>login.jsconst setCookieButton = document.getElementById('set-cookie');
const deleteCookieButton = document.getElementById('delete-cookie');
// 클라이언트 측에서도 credntials 설정 필수
axios.defaults.withCredentials = true;
setCookieButton.onclick = () => {
axios.get('http://localhost:3000')
.then(res => console.log(res))
}
deleteCookieButton.onclick = () => {
axios.delete('http://localhost:3000')
.then(res => console.log(res))
}http://127.0.0.1:5500에서 http://localhost:3000으로 요청할 때, 기본적으로 쿠키가 전달되지 않음.credentials: true를 활성화해야 쿠키를 클라이언트가 받을 수 있음.server.js const express = require("express")
const cors = require("cors")
const cookieParser = require("cookie-parser")
const app = express();
app.use(cors({
origin: ["http://127.0.0.1:5500", "http://localhost:5500"],
methods : ["OPTIONS", "GET", "DELETE"],
// 인증 정보 저장
credentials: true
}))
app.use(cookieParser())
app.get('/', (req, res) => {
// 첫 번째 인자는 쿠키의 이름, 두 번째 인자는 값, 세 번째 인자는 쿠키를 저장할 때 사용할 수 있는 옵션
res.cookie('text-cookie', 'my cookie', {maxAge: 100000, httpOnly: true, secure: true})
res.send('쿠키 생성 완료')
})
app.delete('/', (req, res) => {
// 첫 번째 인자는 삭제하고자 하는 쿠키의 이름, 두 번째 인자는 생성 때 설정했던 옵션 (만료 옵션은 쿠키마다 다를 수 있기 때문에 생략해도 괜찮음. 배포환경에서 다르면 삭제가 안되는 경우도 있음)
res.clearCookie('text-cookie', {httpOnly: true, secure: true})
res.send('쿠키 생성 완료')
})
app.listen(3000, () => console.log('3000번 포트에서 서버 실행'))
const setCookieButton = document.getElementById('set-cookie');
const deleteCookieButton = document.getElementById('delete-cookie');
// 클라이언트 측에서도 credntials 설정 필수
axios.defaults.withCredentials = true;
setCookieButton.onclick = () => {
axios.get('http://localhost:3000')
.then(res => console.log(res))
}
deleteCookieButton.onclick = () => {
axios.delete('http://localhost:3000')
.then(res => console.log(res))
}



| 속성 | 설명 |
|---|---|
| Name | 쿠키의 이름 |
| Value | 쿠키에 저장된 값 |
| Domain | 쿠키가 적용되는 도메인 |
| Path | 쿠키가 유효한 경로 ('/'이면 사이트 전체에서 유효) |
| Expires / Max-Age | 쿠키의 만료 시간 (Session이면 브라우저 종료 시 삭제) |
| Size | 쿠키의 크기 (바이트 단위) |
| HttpOnly | true이면 JavaScript에서 접근 불가 (보안 강화, true 권장) |
| Secure | true이면 HTTPS에서만 쿠키 전송 가능 (true 권장) |
| SameSite | CSRF 방지를 위한 설정 (Lax, Strict, None 가능) |
| Partition Key Site | 브라우저의 쿠키 격리 기능 관련 속성 |
| Cross Site | 쿠키가 사이트 간 요청에서 어떻게 처리되는지 |
| Priority | 쿠키의 우선순위 (Low, Medium, High) |

npm init -y
npm install express cors cookie-parser express-session
const express = require('express')
const cors = require('cors')
const app = express();
app.use(cors({
origin: ["http://127.0.0.1:5500", "http://localhost:5500"],
methods: ["OPTIONS", "POST", "GET", "DELETE"],
credentials: true
}))
const users = [
{
user_id : 'test',
user_password : '1234',
user_name : '테스트 유저',
user_info : '테스트 유저입니다.'
}
]
const cookieParser = require('cookie-parser')
const session = require('express-session')
app.use(cookieParser());
app.use(express.json());
app.use(session({
// 클라이언트 측에 보낼 때 문자열을 암호화
secret: 'session secrete',
// 요청이 들어오면 다시 저장할건지 (값이 같아도 새로 저장할건지?)
resave: false,
// 저장할 내용이 없어도 저장할건지
saveUninitialized : false,
name : 'session_id'
}))
secret: 'session secrete' (필수).env 파일에 보관하는 것이 좋음resave: false (권장)true로 설정하면 같은 데이터라도 요청마다 계속 저장됨 → 불필요한 저장이 발생false가 좋음saveUninitialized: false (권장)false가 좋음true로 설정하면 사용자가 방문만 해도 세션이 저장됨 → 불필요한 저장 증가 가능성 있음name: 'session_id' (선택)'connect.sid'인데, 이를 그대로 사용하면 해커가 쉽게 세션 쿠키를 인식 가능app.listen(3000, () => console.log('3000번 포트에서 서버 실행'))
app.post('/', (req, res) => {
// 클라이언트가 보낸 userId와 userPassword를 req.body에서 구조 분해 할당으로 가져옴
const {userId, userPassword} = req.body;
// users 배열에서 **입력한 userId와 userPassword가 일치하는 사용자를 찾음**
const userInfo = users.find(el => el.user_id ===userId && el.user_password === userPassword)
console.log(req.body)
if (!userInfo) {
// 401 Unauthorized(인증 실패) 상태 코드를 반환하여 로그인 실패를 클라이언트에게 알림
res.status(401).send('로그인 실패')
} else {
// 사용자의 user_id를 세션 객체(req.session)에 저장
req.session.userId = userInfo.user_id;
// 세션이 성공적으로 생성되었음을 클라이언트에게 응답
res.send('세션 생성 완료!');
}
})
app.get('/', (req, res) => {
const userInfo = users.find(el => el.user_id === req.session.userId);
return res.json(userInfo)
})
res.clearCookie()를 사용하여 수동으로 삭제app.delete('/', (req, res) => {
req.session.destroy()
res.clearCookie('session_id')
res.send('세션 삭제 완료')
})
💡
localhost에서 작업할 때 localhost와 172.x.x.x 같은 IP 주소가 다르면 인증 쿠키가 전송되지 않을 수 있으므로 localhost에서 확인
왜 localhost에서 확인해야 할까?
1️⃣ 쿠키는
SameSite정책에 따라 전송이 제한될 수 있음
SameSite정책은 CSRF(사이트 간 요청 위조) 공격을 방지하기 위해 다른 도메인 간의 쿠키 전송을 제한localhost와127.0.0.1은 같은 컴퓨터를 가리키지만, 도메인이 다르다고 간주
2️⃣ localhost와 127.0.0.1이 다르게 인식될 수 있음- 브라우저는
localhost를 로컬 환경으로 특별 취급하지만,127.0.0.1은 IP 주소로 인식localhost에서secure: false로 설정된 쿠키는 전송되지만,127.0.0.1에서는 HTTPS가 아니라면 쿠키가 차단될 수 있음
3️⃣Secure옵션이 활성화된 경우res.cookie('session_id', 'value', { secure: true })
secure: true이면 HTTPS 환경에서만 쿠키가 전송됨localhost에서는 HTTP에서도 작동하지만,127.0.0.1,172.x.x.x같은 IP 주소에서는 HTTPS가 필요할 수도 있음- 따라서 개발 환경에서는
secure: false로 설정.
4️⃣ 도메인이 다르면 쿠키가 다르게 저장됨http://localhost:3000에서 로그인한 후,
→http://127.0.0.1:3000으로 접속하면 쿠키가 보이지 않을 수 있음- 이유: 쿠키는 도메인별로 저장되기 때문에,
localhost에서- 개발할 때 항상 localhost에서 테스트
- CORS 설정에서
origin: ['http://localhost:3000']을 명확하게 지정