본문 바로가기

Programming/Node.js

5. http 모듈로 서버 만들기 (3) - 쿠키와 세션의 이해 [4]

node js logo image

 

 

 

 

앞선 아티클에서 쿠키를 통한 유저 식별 사례 예제 코드를 작성했습니다. 이어서 계속 설명해 보겠습니다.

 

 

[cookie2.html]

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>COOKIE & SESSION SAMPLE</title>
</head>
<body>
    <form action="/login">
        <input id="name" name="name" placeholder="enter the name" />
        <button id="login">LOGIN</button>
    </form>
</body>
</html>

 

 

 

[cookie2.js]

const http = require('http');
const fs = require('fs').promises;
const path = require('path');

// *1번 시작
const parseCookies = (cookie = '') => 
    cookie
        .split(';')
        .map(v => v.split('='))
        .reduce((acc, [k, v]) => {
            acc[k.trim()] = decodeURIComponent(v);
            return acc;
        }, {});
// 1번 끝*

// *2번 시작
http.createServer(async (req, res) => {
    const cookies = parseCookies(req.headers.cookie);

    // 주소가 /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 { // 주소가 /이면서 name이라는 쿠키가 없는 경우
        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번 포트 서버 대기 중');
    });

 

 

우선 기본적으로 주소는 [/login]과 [/] 두 개입니다. 그러므로 주소별로 분기 처리를 진행하겠습니다. 참고로 http://localhost:8084로 접속하면 [/] 요청을 보내게 되고 cookie2.html에서 form을 통해 로그인 요청을 보내게 되면 /login 으로 요청을 보냅니다. 코드 상 실제로 제일 먼저 실행되는 부분은 else 영역이 되겠네요(주소가 /이면서 name이라는 쿠키가 있는 경우)

 

 

1번 영역을 먼저 살펴보겠습니다. 쿠키는 기본적으로 mycookie=test와 같은 문자열 타입의 데이터입니다. 하지만 parseCookies 함수는 쿠키 문자열을 JS 객체 타입으로 변환해 줍니다. { mycookie: 'test' }와 같이 변하게 되는 것이죠. 여기서 함수 내부의 내용은 크게 신경쓰지 말고, parseCooies 함수가 문자열을 객체로 변환한다는 사실만 기억하면 됩니다.