Programming/Node.js

Node.js :: Express 로 Cookie 올바르게 활용하기

고고마코드 2022. 6. 8. 13:58
반응형

이 예제에는 두 가지 패키지를 사용하고 있습니다. (cookie는 없어도 됩니다)
express: 4.18.1 cookie: 0.5.0


기본 예제 틀 만들기

const express = require('express');
const app = express();

app.use(express.urlencoded({ extended: false }));

app.get('/', (req, res) => {
    let html = `
        <form action="/cookie" method="post">
            <input type="text" name="c_val" value="" />
            <input type="submit" value="cookie" />
        </form>
    `;
    res.send(html);
});

app.post('/cookie', (req, res) => {
    res.send('cookie test!');
});

app.listen(3000, () => {
    console.log('Example app listening on port 3000!');
});

단순하게 localhost:3000 에서 cookie 버튼을 클릭하면 쿠키를 생성하고 읽는 예제이며, 해당 예제를 위한 기본 소스입니다.

쿠키 저장하기

기본

app.post('/cookie', (req, res) => {
    let post = req.body;

    res.cookie('c_val', post.c_val);

    res.send('cookie test!');
});

post로 전송받은 c_val 데이터를 가져와 쿠키를 저장하는 기본적인 방법입니다.

저장 후 다시 예제를 확인한 후 개발자 도구에서 쿠키를 확인할 수 있습니다.

단순히 이름, 값 외에 여러가지 옵션들이 있는데, 자세한 내용은 공식 문서의 내용을 참조합니다.

해당 링크는 본문 하단 참조를 확인하세요.

옵션 설정

  • domain, path
res.cookie('c_val_domain_path', post.c_val, { domain: 'example.com', path: '/admin' });

c_val_domain 에는 domain 과 path 가 설정된 것을 확인할 수 있습니다.

domain에 경고가 발생하는 이유는 현재 domain 은 localhost 인데 example.com 으로 설정했기 때문에 발생하는 것입니다.

만약 위처럼 설정했다면 c_val_domain 쿠키는 *.example.com 내에서 쿠키를 사용할 수 있으며, /admin 경로내에서 사용할 수 있습니다.

  • httpOnly
res.cookie('c_val_httpOnly', post.c_val, { httpOnly: true });

httpOnly 속성은 웹서버를 통해 접근했을 경우에만 쿠키를 사용할 수 있습니다.

예를 들어 개발자도구 콘솔 창에서 document.cookie 를 입력하면 현재 브라우저의 쿠키를 확인할 수 있습니다.

c_val 은 확인이 되지만, c_val_httpOnly 는 javascript console 로는 확인이 되지 않습니다.

  • maxAge
res.cookie('c_val_maxAge', post.c_val, { maxAge: 900000 });

현재 시간을 기준으로 만료시기를 밀리 초 단위로 설정할 수 있습니다.

  • secure
res.cookie('c_val_secure', post.c_val, { secure: true });

http 에서는 사용할 수 없고, https 에서만 사용할 쿠키를 사용할 수 있습니다.

  • 쿠키 삭제
res.clearCookie('c_val_secure');

이 외의 자세한 방법은 게시글 하단 참조에서 공식 문서를 참고하세요.


쿠키 불러오기

const cookie = require('cookie');

app.get('/cookie_check', (req, res) => {
    let html = '';

    let cookies = {};
    if (req.headers.cookie !== undefined) {
        cookies = cookie.parse(req.headers.cookie);
    }

    Object.keys(cookies).forEach((key) => {
        html += `<p>key: ${key}, value:${cookies[key]}</p>`
    });

    res.send(html);
})

저는 간편하게 cookie를 불러와 사용하기 위해서 cookie 패키지를 사용했습니다.

사용한 이유는 req.headers.cookie 를 출력하면 아래와 같이 출력이 됩니다.

c_val=hello; c_val_httpOnly=hello; c_val_maxAge=hello

이 쿠키를 사용하기 위해서는 다시 세미콜론을 기준으로 잘라서 써야하는 가공 작업이 필요합니다.

그러나 cookie 패키지를 사용하면 json 으로 만들어주기 때문에 위의 코드처럼 간단히 사용할 수 있습니다.

  • javasciprt 만으로 cookie json 으로 가져오기

만약 쿠키를 불러올 때 node 를 활용할 수 없다면 단순 javasciprt 로도 불러올 수 있습니다.

// document.cookie to json
var cookies = {};
document.cookie.split(/\s*;\s*/).forEach(function(pair) {
  pair = pair.split(/\s*=\s*/);
  cookies[pair[0]] = pair.splice(1).join('=');
});

앞서 설명한 document.cookie 는 브라우저의 현재 cookie 목록을 가져오는데, 이를 json 형식으로 변환하는 코드입니다.

단, 다른 옵션들에 의해 cookie 목록을 가져오지 못할 수도 있으니, cookie 옵션을 정확하게 설정해 주어야 합니다.


전체 코드

const cookie = require('cookie');
const express = require('express');
const app = express();

app.use(express.urlencoded({ extended: false }));

app.get('/', (req, res) => {
    let html = `
        <form action="/cookie" method="post">
            <p>
                <input type="text" name="c_val" value="" />
                <input type="submit" value="cookie" />
            </p>
        </form>
    `;
    res.send(html);
});

app.post('/cookie', (req, res) => {
    let post = req.body;

    res.cookie('c_val', post.c_val);
    res.cookie('c_val_domain_path', post.c_val, { domain: 'example.com', path: '/admin' });
    res.cookie('c_val_httpOnly', post.c_val, { httpOnly: true });
    res.cookie('c_val_maxAge', post.c_val, { maxAge: 900000 });
    res.cookie('c_val_secure', post.c_val, { secure: true });

    res.send('cookie test!');
});

app.get('/cookie_check', (req, res) => {
    console.log(req.headers.cookie);

    let html = '';
    let cookies = {};
    if (req.headers.cookie !== undefined) {
        cookies = cookie.parse(req.headers.cookie);
    }

    Object.keys(cookies).forEach((key) => {
        html += `<p>key: ${key}, value:${cookies[key]}</p>`
    });

    res.send(html);
})

app.listen(3000, () => {
    console.log('Example app listening on port 3000!');
});

참고자료

  1. https://expressjs.com/ko/4x/api.html

반응형