✅ 쿠키
클라이언트의 정보를 기억하기 위해
서버는 요청에 대한 응답으로 쿠키를 같이 보내고
클라이언트의 웹 브라우저는 다음 요청에
쿠키를 자동으로 같이 보내어
서버가 쿠키를 읽고 클라이언트가 누구인지 파악한다
쿠키는 request의 헤더(Cookie)에 담겨 서버에 전송된다
브라우저는 response의 header (Set-Cookie)를 읽어서 저장한다
const http = require('http');
const PORT = 8080;
http.createServer(async (req, res) =>{
try{
console.log(req.url, req.headers.cookie);
res.writeHead(200, {'Set-Cookie' : 'name=gengminy'});
return res.end('hello my cookie');
} catch(err){
console.error(err);
res.writeHead(404, {'Content-Type' : 'text/html; charset=utf-8'});
res.end(err.message);
}
}
).listen(PORT, ()=>{
console.log(`server online on port ${PORT}!`);
});
새로고침 후 두번째 요청부터 쿠키를 서버가 읽어 콘솔에 출력된다
✅ Set-Cookie 옵션
- {name}={value} : {name}={value}에 해당하는 쿠키를 설정
- Expires={Date} : {Date}에 해당하는 만료 기간을 설정하여 이 기간이 되면 쿠키 삭제
- Max-age={second} : 날짜 대신 {second}초 만큼 지나면 쿠키 삭제
- Domain={Domain} : 쿠키가 전송될 도메인을 {Domain}으로 지정, 기본값은 현재 도메인
- Path={URL} : 쿠키가 전송될 URL을 지정 가능, 기본 값은 '/'
- Secure : HTTPS 사용 환경에서만 쿠키 전송 가능
- HttpOnly : 자바스크립트에서 쿠키에 접근할 수 없도록 지정, 쿠키 조작 방지 위해 사용
🔨 예제
const http = require('http');
const fs = require('fs').promises;
const url = require('url');
const qs = require('querystring');
const parseCookies = (cookie = '') =>
cookie
.split(';')
.map(v => v.split('='))
.reduce((acc, [k, v]) => {
acc[k.trim()] = decodeURIComponent(v);
return acc;
}, {});
http.createServer(async (req, res) => {
const cookies = parseCookies(req.headers.cookie);
if (req.url.startsWith('/login')) {
const { query } = url.parse(req.url);
const { name } = qs.parse(query);
const expires = new Date();
// 쿠키 유효 시간을 현재시간 + 5분으로 설정
expires.setMinutes(expires.getMinutes() + 5);
res.writeHead(302, {
Location: '/',
'Set-Cookie': `name=${encodeURIComponent(name)};
Expires=${expires.toGMTString()}; HttpOnly; Path=/`,
});
res.end();
} else if (cookies.name) {
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end(`${cookies.name}님 안녕하세요`);
} else {
try {
const data = await fs.readFile('./login.html');
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(data);
} catch (err) {
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end(err.message);
}
}
})
.listen(8080, () => {
console.log('8080번 포트에서 서버 대기 중입니다!');
});
쿠키가 존재하여 새로고침해도 로그인 정보가 남아있다
하지만 이러한 방식은 쿠키가 노출되어있어 상당히 위험하다
🔨 세션 예제
사용자 정보가 노출되지 않게 서버측에서 정보를 관리하며
예제에서는 uniqueInt 라는 숫자 값을 대신 보내어
이 값을 통해 서버와 클라이언트가 소통하게 된다
const http = require('http');
const fs = require('fs').promises;
const url = require('url');
const qs = require('querystring');
const parseCookies = (cookie = '') =>
cookie
.split(';')
.map(v => v.split('='))
.reduce((acc, [k, v]) => {
acc[k.trim()] = decodeURIComponent(v);
return acc;
}, {}
);
const session = {};
http.createServer(async (req, res) => {
const cookies = parseCookies(req.headers.cookie);
if (req.url.startsWith('/login')) {
const { query } = url.parse(req.url);
const { name } = qs.parse(query);
const expires = new Date();
expires.setMinutes(expires.getMinutes() + 5);
const uniqueInt = Date.now();
session[uniqueInt] = {
name,
expires,
};
res.writeHead(302, {
Location: '/',
'Set-Cookie': `session=${uniqueInt}; Expires=${expires.toGMTString()}; HttpOnly; Path=/`,
});
res.end();
// 세션쿠키가 존재하고, 만료 기간이 지나지 않았다면
} else if (cookies.session && session[cookies.session].expires > new Date()) {
res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end(`${session[cookies.session].name}님 안녕하세요`);
console.log(session[cookies.session]);
} else {
try {
const data = await fs.readFile('./login.html');
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(data);
} catch (err) {
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end(err.message);
}
}
})
.listen(8080, () => {
console.log('8080번 포트에서 서버 대기 중입니다!');
});
그러나 이와 같은 방법 또한 세션 아이디가 노출되어 있기 때문에 보안상 취약하며
다른 검증된 코드나 모듈을 사용하는 것이 좋다
'📡 백엔드 > ⭐ Node.js' 카테고리의 다른 글
[Nodejs] Sequelize 로 SQL 데이터베이스 연동하기 (0) | 2022.05.21 |
---|---|
[Nodejs] Router 객체로 라우팅 파일 분리 (0) | 2022.05.17 |
[Nodejs] 미들웨어의 사용과 자주 쓰이는 미들웨어 (0) | 2022.05.16 |
[Nodejs] express 서버 열기 (0) | 2022.05.15 |
[Nodejs] http 모듈로 간단한 REST API 사용 (0) | 2022.05.15 |