해당 내용은 제로초님의 Node.js 강의를 정리한 글 입니다.
더 자세한 내용은 아래 링크는 해당 강의입니다.
https://www.inflearn.com/course/%EB%85%B8%EB%93%9C-js-%EA%B5%90%EA%B3%BC%EC%84%9C/dashboard
[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지 강의 | 제로초(조현영) - 인프런
제로초(조현영) | 노드가 무엇인지부터, 자바스크립트 최신 문법, 노드의 API, npm, 모듈 시스템, 데이터베이스, 테스팅 등을 배우고 5가지 실전 예제로 프로젝트를 만들어 나갑니다. 클라우드에 서
www.inflearn.com
쿠키의 필요성
⇒ 요청애는 한 가지 단점이 있음
- 누가 요청을 보냈는지 모름
- 로그인을 구현하면 됨
- 쿠키와 세션이 필요
⇒ 쿠키 : 키 = 값의 쌍
- name = choring
- 매 요청마다 서버에 동봉해서 보냄
- 서버는 쿠키를 읽어 누구인지 파악
쿠키 서버 만들기
⇒ 쿠키 넣는 것을 직접 구현
- writeHead: 요청 헤더에 입력하는 메서드
- Set-Cookie: 브라우저에게 쿠키를 설정하라고 명령
⇒ 쿠키: 키=값의 쌍
- name = choring
- 매 요청마다 서버에 동봉해서 보냄
쿠키로 나를 식별하기
⇒ 쿠키에 내 정보를 입력
- parseCookies: 쿠키 문자열을 객체로 변환
- 주소가 /login인 경우와 /인 경우로 나뉨
- /login 인 경우 쿼리스트링으로 온 이름을 쿠키로 저장
- 그 외의 경우 쿠키가 있는지 없는지 판단
- 있으면 환영 인사
- 없으면 로그인 페이지로 리다이렉트
<!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').promises;
const path = require('path');
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); // { mycookie: 'test' }
// 주소가 /login으로 시작하는 경우
if (req.url.startsWith('/login')) {
const url = new URL(req.url, 'http://localhost:8084');
const name = url.searchParams.get('name');
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(path.join(__dirname, '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(8084, () => {
console.log('8084번 포트에서 서버 대기 중입니다!');
});
쿠키 옵션
⇒ Set-Cookie 시 다양한 옵션이 있음
- 쿠키명 = 쿠키값: 기본적인 쿠키의 값이다. mycookie=test 또는 name=choring 같이 설정한다.
- Expires = 날짜: 만료 기한이다. 이 기한이 지나면 쿠키가 제거된다. 기본값은 클라이언트가 종료될 때까지이다.
- Max-age = 초: Expires와 비슷하지만 날짜 대신 초를 입력할 수 있다. 해당 초가 지나면 쿠키가 제거된다. Expires 보다 우선된다.
- Domain = 도메인명: 쿠키가 전송될 도메인을 특정할 수 있다. 기본값은 현재 도메인이다.
- Path = URL: 쿠키가 전송될 URL을 특정할 수 있다. 기본값은 “/”이고 이 경우 모든 URL에서 쿠키를 전송할 수 있다.
- Secure: HTTPS일 경우에만 쿠키가 전송된다.
- HttpOnly: 설정 시 자바스크립트에서 쿠키에 접근할 수 없다. 쿠키 조작을 방지하기 위해 설정하는 것이 좋다.
쿠키 서버 실행하기
⇒ localhost:8084 포트에 접속
- Application 탭 열기
- 로그인을 하면 쿠키가 생성됨
⇒ [localhost:8084](http://localhost:8084) 포트에 접속
- Application 탭 열기
- 로그인을 하면 쿠키가 생성됨
세션 사용하기
⇒ 쿠키의 정보는 노출되고 수정되는 위험이 있음
- 중요한 정보는 서버에서 관리하고 클라이언트에는 세션 키만 제공
- 서버에 세션 객체(session) 생성 후, uniqueInt(키)를 만들어 속성명으로 사용
- 속성 값에 정보 저장하고 uniqueInt를 클라이언트에 보냄
const http = require('http');
const fs = require('fs').promises;
const path = require('path');
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 url = new URL(req.url, 'http://localhost:8085');
const name = url.searchParams.get('name');
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(path.join(__dirname, '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(8085, () => {
console.log('8085번 포트에서 서버 대기 중입니다!');
});
반응형
'백엔드 > Node' 카테고리의 다른 글
#6 npm (3) | 2025.02.03 |
---|---|
#5 cluster (1) | 2025.02.01 |
#3 REST API 와 라우팅 (2) | 2025.01.28 |
#2 요청과 응답 이해하기 (3) | 2025.01.25 |
#1 Node란? (2) | 2025.01.24 |