쿠키의 역할
- 클라이언트가 누구인지 기억하기 위해서 서버는 요청에 대한 응답을 할 때 쿠키라는 것을 같이 보내준다.
- 클라이언트는 서버로 요청 할 때 마다 서버로부터 받은 쿠키를 같이 보내주어 클라이언트가 누구인지를 파악한다.
- 쿠키는 요청과 응답의 헤더에 저장된다.
서버에서 쿠키를 만들어 요청자의 브라우저의 넣기
const http = require('http');
const parseCookies = (cookie = '')=>
cookie
.split(';')
.map(v=> v.split('='))
.map(([k, ...vs]) => [k, vs.join('=')])
.reduce((acc, [k, v]) => {
acc[k.trim()] = decodeURIComponent(v);
return acc;
}, {});
http.createServer((req, res) => {
const cookies = parseCookies(req.headers.cookie);
console.log(req.url, cookies);
res.writeHead(200, { 'Set-Cookie': 'mycookie = test' });
res.end('Hello Cookie');
})
.listen(8082, () => {
console.log('8082번 포트에서 서버 대기 중입니다!');
});
코드설명
- 쿠키는 name=kwon;year=2019처럼 문자열 형식으로 오는 데이터를 {name: 'kwon', year: '2019'}와 같이 객체로 바꾸는 함수이다.
- createserver 메서드의 콜백에서는 제일 먼저 req 객체에 담겨 있는 쿠키를 분석한다.
- (req.headers.cookie)
- 응답의 헤더에 쿠키를 기록해야 하므로 res.writeHead 메서드를 사용한다.
- Set-Cookie는 브라우저에게 다음과 같은 값의 쿠키를 저장하라는 의미이다.
결과:
8082번 포트에서 서버 대기 중입니다! / { '': '' } /favicon.ico { mycookie: 'test' } |
결과를 확인해보면 { : }과 쿠키( { mycookie: 'test'})값 옆에 favicon.ico 두 가지 요청이 있다.
처음 브라우저가 서버에 요청을 할 때 쿠키를 가지고 있지 않아서 공백이 찍히고 서버에서 쿠키를 가지고 있지 않으니까 쿠키를 심으라고 브라우저에서 명령하므로써 두번째 요청도 같이 들어온다.
두 번째의 왼쪽부분은 req.url이고 파비코은 웹 사이트 탭 옆에 보이는 이미지를 뜻한다.
-> 브라우저는 파비콘이 뭔지 html에서 유추할 수 없으면 서버에 파비콘 정보에 대한 요청을 보낸다.
위 예제가 그러한 경우이므로 브라우저가 추가로 favicon.ico를 요청한 것이다.
쿠키가 나인지를 식별하기
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>쿠키&세션</title>
</head>
<body>
<form action="/login">
<input id="name" name="name" placeholder="이름을 입력하세요" />
<button id="login">로그인</button>
</form>
</body>
</html>
const http = require('http');
const fs = require('fs');
const url = require('url');
const qs = require('querystring');
const parseCookies = (cookie = '')=>
cookie
.split(';')
.map(v=> v.split('='))
.map(([k, ...vs]) => [k, vs.join('=')])
.reduce((acc, [k, v]) => {
acc[k.trim()] = decodeURIComponent(v);
return acc;
}, {});
http.createServer((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);
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/html; charset=utf-8' });
res.end(`${cookies.name}님 안녕하세요`);
}else{
fs.readFile('./server4.html', (err, data) => {
if(err){
throw err;
}
res.end(data);
});
}
})
.listen(8083, () => {
console.log('8083번 포트에서 서버 대기 중입니다!');
});
코드설명
- 클라이언트가 root 주소로 요청을 하게 되면 else 부분으로 요청이 들어와 server4.html 파일을 보여준다.
- 클라이언트가 server4.html에서 name을 입력하고 전송을 하면 /login 주소로 요청이되고 if문에 걸리게 된다.
- url 부분들을 해석하고 쿠키 조건을 만든다음 res.wirteHead로 redirect 상태코드를 주어 루트 주소로 쿠키와 함께 재요청을 하게 한다.
- 재요청이 들어오면 이제 쿠키가 존재하기 때문에 else if에 들어가게 되고 성공 상태코드를 response해준다.
쿠키 설정시 사용하는 옵션들
- 쿠키명=쿠키값
- Expires=날짜: 쿠키가 보존되는 기간
- Max-agee=초: Expires와 비슷하지만 날짜 대신 초를 입력가능
- Domin=도메인명: 쿠키가 전송될 도메인을 특정함. 기본값은 현재 도메인
- Path=URL: 쿠키가 전송될 URL을 특정함. 기본값은 '/'
- Secure: HTTPS: HTTPS일 때만 쿠키 전송가능
- HttpOnly: 설정 시 자바스크립트에서 쿠키에 접근할 수 없다.
위 코드는 쿠키가 노출, 조작될 위험이 있다.
서버가 사용자 정보를 관리
const http = require('http');
const fs = require('fs');
const url = require('url');
const qs = require('querystring');
const parseCookies = (cookie= '') =>
cookie
.split(';')
.map(v => v.split('='))
.map(([k, ...vs]) => [k, vs.join('=')])
.reduce((acc, [k, v]) => {
acc[k.trim()] = decodeURIComponent(v);
return acc;
}, {})
const session = {};
http.createServer((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 randomInt = Date.now();
session[randomInt] = {
name,
expires,
};
res.writeHead(302, {
Location: '/',
'Set-Cookie': `session=${randomInt}; Expires=${expires.toGMTString()}; HttpOnly; Path=/`,
});
res.end();
}else if(cookies.session && session[cookies.session].expires> new Date()) {
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(`${session[cookies.session].name}님 안녕하세요`);
}else {
fs.readFile('./server4.html', (err, data) => {
if (err) {
throw err;
}
res.end(data);
});
}
})
.listen(8084, () =>{
console.log('8084번 포트에서 서버 대기 중입니다.');
});
쿠키를 보낼 때 이름대신 randomInt라는 임의의 숫자를 전송하고 쿠키의 이름과 만료시간을 session이라는 객체에
넣는다. session객체의 인덱스 randomInt에 이름과 만료시간을 넣어놓고 정보를 접근하여 사용한다.
'Javascript > Node.js' 카테고리의 다른 글
Https와 Http2 (0) | 2019.11.06 |
---|---|
Rest API와 라우팅 (0) | 2019.11.06 |
이벤트 이해하기 (0) | 2019.10.19 |
요청과 응답 이해하기(서버구현) (0) | 2019.10.19 |
버퍼와 스트림 이해하기 (0) | 2019.10.17 |
댓글