웹 사이트에 방문해서 로그인을 할 때 쿠키와 세션을 사용합니다. 서버에서 누구인지 기억하기 위해서는 요청에 대한 응답을 할 때 쿠키를 같이 보냅니다. 즉, 서버는 미리 클라이언트에 요청자를 추정할만한 정보를 쿠키로 만들어 보내고 그 다음부터는 클라이언트로부터 쿠키를 받아 요청자를 파악합니다. 먼저 쿠키를 생성하는 것부터 알아보겠습니다.
쿠키 생성하기
const http = require('http');
http.createServer((req, res) => {
console.log(req.url, req.headers.cookie);
res.writeHead(200, { 'Set-Cookie': 'mycookie=test' }); // 쿠키 생성
res.end('Hello Cookie');
})
.listen(8080, () => {
console.log('8080번 포트에서 서버 대기 중입니다!');
});
쿠키는 요청의 헤더에 담겨 전송되고 응답의 헤더에 저장합니다. 그래서 res.writeHead 메서드를 통해 응답의 헤더에 쿠키를 저장합니다. 쿠키는 name=hong 처럼 문자열 형식으로 존재하고 왼쪽은 쿠키 이름, 오른쪽은 쿠키 값입니다.
'Set-Cookie': 'mycookie=test' 는 mycookie=test 라는 값의 쿠키를 저장하라는 의미입니다. 서버를 실행시키고 웹에 접속하면 콘솔에 위의 결과처럼 저장된 쿠키를 확인할 수 있습니다.
쿠키를 사용해 사용자를 식별하기
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);
// 주소가 /login으로 시작하는 경우
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();
// name이라는 쿠키가 있는 경우
} 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('./cookie2.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번 포트에서 서버 대기 중입니다!');
});
1. 주소가 /login 으로 시작되는 경우
qs.parse(query) - querystring 모듈을 사용해 query를 분석합니다.
expires.setMinutes(expires.getMinutes() + 5); - 쿠키 만료 시간을 설정합니다. 쿠키 만료 시간은 현재 시간으로부터 5분 뒤로 설정했습니다.
res.writeHead(응답코드, 헤더정보) - 응답헤더에 대한 정보를 기록합니다. Location은 리다이렉션 주소를 의미합니다. Set-Cookie로 쿠키를 저장할 수 있습니다. 헤더에는 한글을 설정할 수 없으므로 한글은 encodeURIComponent 로 감싸서 넣어야 합니다. Expires로 쿠키 만료 기한을 설정할 수 있습니다. 쿠키 조작 방지를 위해 HttpOnly를 설정하였습니다. Path는 쿠키가 전송될 URI를 의미합니다.
2. 주소가 /login 으로 시작되지 않는 경우 (/ 으로 접속했을 때)
쿠키가 있는지 없는지 확인한후 쿠키가 없으면 로그인 페이지로 보냅니다. 쿠키가 있으면 "~님 안녕하세요" 라는 메세지가 페이지에 보여집니다.
쿠키를 사용하면 Application 탭에서 쿠키가 보여집니다. 이렇게 되면 쿠키가 조작될 위험이 있고 개인정보가 노출될 수 있습니다. 이것을 막기 위해 세션을 사용을 사용합니다.
세션을 사용해 사용자를 식별하기
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}님 안녕하세요`);
} else {
try {
const data = await fs.readFile('./cookie2.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번 포트에서 서버 대기 중입니다!');
});
실행 결과는 쿠키를 사용했을 때와 같습니다. 위 코드는 사용자 정보는 서버에 저장하고 쿠키에 세션 아이디를 저장하는 방식입니다. 세션을 위해 사용하는 쿠키를 세션 쿠키라고 합니다.
session[uniqueInt] = { name, expires, }; - session객체에 사용자의 이름과 만료시간을 저장합니다.
res.writeHead() - Set-Cookie로 쿠키에 세션 아이디를 저장합니다.
'Back-end > Node.js' 카테고리의 다른 글
[Node.js] 미들웨어 (0) | 2021.07.13 |
---|---|
[Node.js] Express 프로젝트 생성하기 (0) | 2021.07.11 |
[Node.js] 요청과 응답 서버 (http) (0) | 2021.07.10 |
[Node.js] 파일 시스템 모듈(fs), 이벤트 (0) | 2021.07.09 |
[Node.js] 노드 내장 모듈 알아보기 (0) | 2021.07.07 |