클라이언트에서 보내는 요청에는 단점이 존재합니다.
누가 요청을 보내는지 모른다는 것입니다.
그렇기 때문에 로그인을 구현해야합니다.
로그인을 구현하기 위해 쿠키와 세션에 대해서 알아야 합니다.
쿠키는 웹 브라우저가 서버와의 통신에서 사용하는 작은 데이터 조각입니다. 사용자의 로그인 정보나 세션 정보 등을 저장하는 데 사용됩니다.
요청을 보낸 사람이 누구인지 기억하기 위해 서버는 요청에 대한 응답을 할 때 쿠키하는 것을 같이 보냅니다.
서버로부터 쿠키가 오면, 웹 브라우저는 쿠키를 저장해뒀다가 다음에 요청할 때마다 쿠키를 동봉해서 보냅니다.
서버는 요청에 들어 있는 쿠키를 읽어서 사용자가 누구인지 파악합니다.
브라우저는 쿠키가 있다면 자동으로 동봉해서 보내주므로 따로 처리할 필요가 없습니다.
1 2 3 4 5 6 7 8 9 | 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(8083, () => { console.log("8083번 포트에서 서버 대기 중입니다!"); }); | cs |




1 2 3 4 5 6 7 8 9 10 11 12 13 | <!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> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 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번 포트에서 서버 대기 중입니다!"); }); | cs |
parseCookies 함수
req.headers.cookie

url.searchParams.get("name")
요청된 url에서 name이라는 특정 쿼리 파라미터 값을 추출합니다.

Location
리다이렉트 주소입니다.
name=${encodeURIComponent(name)}
name의 정보를 쿠키에 넣어줍니다.

Expires=${expires.toGMTString()}
쿠키 유효 시간입니다.
HttpOnly
설정 시 자바스크립트에서 쿠키에 접근할 수 없습니다. 쿠키 조작을 방지하기 위해 설정하는 것이 좋습니다.
Path=URL
쿠키가 전송될 URL을 특정할 수 있습니다.
서버에 사용자 정보를 저장하고 클라이언트와는 세션 아이디로만 소통합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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번 포트에서 서버 대기 중입니다!"); }); | cs |