상세 컨텐츠

본문 제목

Node. js / 라우터 분기 처리 / 쿠키 수집 part 2

프레임워크+라이브러리/Express

by moonionn 2020. 7. 21. 15:54

본문

Lou Montulli, who devised Cookies

 

 

복수의 쿠키 등록하기

지난 part 1에서는 사용자의 이름과 생년월일 정보를 받았지만, 쿠키에는 이름만 등록을 했었습니다.

이번에는 생년월일도 쿠키에 등록해보겠습니다.

다수의 쿠키 정보를 등록하려 할 때는 'Set-Cookie' : [] 를 이용해야 합니다.

const http = require('http');
const fs = require('fs');
const url = require('url');
const qs = require('querystring');

const server = http.createServer((req, res) => {

  const {pathname} = url.parse(req.url);
  const {query} = url.parse(req.url);
  const {name} = qs.parse(query);
  const birthDate = qs.parse(query).birth_date;

  if (pathname === '/user'){
  
    res.writeHead(200, {
      'Set-Cookie' : [
        `name = ${encodeURIComponent(name)}`, 
        `birth date = ${birthDate}`
      ],
      'Content-Type':'text/plain; charset=utf-8'
    });
    
    res.end(`OK! We've received your profile.
    \nYour name : ${name}, 
    \nYour birthdate : ${birthDate}`);
    
  } else {
    fs.readFile('./server_content.html', (err, data) => {
      res.writeHead(200, {'Set-Cookie': 'user-info = testing'});
      res.end(data);
    });
  };
});

server.listen(8000);

 

 

또한 Network - Headers의 목록을 보면,

코드가 writeHead()를 사용하고 있기 때문에

Response Headers에 Set-Cookie가 표기되는 걸 볼 수 있습니다.

 

 

// 'Set-Cookie' : [
// `name = ${encodeURIComponent(name)}`,
// `birth date = ${birthDate}`
// ]

이렇게 쿠키 세팅 코드를 주석처리하게 된다면, Response Headers에 더 이상 Set-Cookie는 뜨지 않겠지만,

Request Headers에 여전히 Cookie가 남아있는 걸 확인할 수 있습니다.

 

 

(+중간 수정) birth date의 에러

쿠키의 이름값에 띄어쓰기를 했더니 아래와 같은 오류가 발생합니다.

Name값에는 아무것도 쓰여있지 않고 Value값에 엉뚱한 'birth'가 들어가 있습니다.

바로 아래의 코드가 문제인데요,

 

'Set-Cookie' : [
`name = ${encodeURIComponent(name)}`,
`birth date = ${birthDate}`
]

이 부분을

birth date와 birthDate를 모두 포함해 모든 이름을 birth_date로 통합시켰습니다.

 

 

아래는 수정된 코드 전체입니다.

const http = require('http');
const fs = require('fs');
const url = require('url');
const qs = require('querystring');

const server = http.createServer((req, res) => {

  const {pathname} = url.parse(req.url);
  const {query} = url.parse(req.url);
  const {name, birth_date} = qs.parse(query);

  if (pathname === '/user'){
  
    res.writeHead(200, {
      'Set-Cookie' : 
      [
        `name = ${encodeURIComponent(name)}`, 
        `birth_date = ${birth_date}`
      ],
      'Content-Type':'text/plain; charset=utf-8'
    });
    
    res.end(`OK! We've received your profile.
    \nYour name : ${name}, 
    \nYour birthdate : ${birth_date}`);
    
  } else {
  
    fs.readFile('./server_content.html', (err, data) => {
      res.writeHead(200, {'Set-Cookie': 'user-info = testing'});
      res.end(data);
    });
  };
});

server.listen(8000);

 

이렇게 바꾸어 다시 시도해보면 정상적으로 쿠키가 입력됩니다.

 

등록된 쿠키 사용하기 (쿠키 읽기)

등록된 쿠키에 접근하기 위해서는 Request를 통해야 합니다.

콘솔창에 req.headers.cookie를 치면 쿠키를 읽어올 수 있습니다.

const http = require('http');
const fs = require('fs');
const url = require('url');
const qs = require('querystring');

const server = http.createServer((req, res) => {
  const {pathname} = url.parse(req.url);
  const {query} = url.parse(req.url);
  const {name, birth_date} = qs.parse(query);

  if (pathname === '/user'){
    res.writeHead(200, {
      'Set-Cookie' : 
      [
        `name = ${encodeURIComponent(name)}`, 
        `birth_date = ${birth_date}`
      ],
      'Content-Type':'text/plain; charset=utf-8'
    });

    //req.heades.cookie 찍어보기
    console.log(req.headers.cookie);

    res.end(`OK! We've received your profile.
    \nYour name : ${name}, 
    \nYour birthdate : ${birth_date}`);
  } else {
    fs.readFile('./server_content.html', (err, data) => {
      res.writeHead(200, {'Set-Cookie': 'user-info = testing'});
      
      //req.heades.cookie 찍어보기
      console.log(req.headers.cookie);
    
      res.end(data);
    });
  };
});
server.listen(8000);

 

맨 처음 localhost:8000 번으로 들어간 후, 

이름과 생년월일을 입력하고 정보를 확인하는 페이지로 가기까지의 콘솔 변화 과정은 아래와 같습니다.

 

0|server | undefined
0|server | user-info=testing
0|server | user-info=testing
0|server | user-info=testing; name=%EB%B6%88%ED%83%80%EB%8A%94%20%ED%82%A4%EB%B3%B4%EB%93%9C; birth_date=2020-04-01

 

npm cookie 모듈 설치

저장된 쿠키 데이터를 활용하기 위해서는 위와 같은 불친절한 쿠키 나열을 쪼개 활용해야 합니다.

첫번째 방법은 쿠키 파싱을 위한 함수를 작성하는 것인데, 이는 어려운 내용이니 넘어가도록 하겠습니다.

const parseCookies = (cookie = '') => cookie
  .split(';')
  .map(v => v.split('='))
  .map(([k, ...vs]) => [k, vs.join('=')])
  .reduce((acc, [k, v]) => {
    acc[k.trim()] = decodeURLComponent(v);
    return acc; 
  }, {});
  
//코드 출처: zerocho blog, 
//https://www.zerocho.com/category/etc/post/5b4c1d716a3abe001b94de12

//or

function parseCookies (request) {
  var list = {},
  rc = request.headers.cookie;
  rc && rc.split(';').forEach(function( cookie ) {
    var parts = cookie.split('=');
    list[parts.shift().trim()] = decodeURI(parts.join('='));
  });
  return list;
}

//코드 출처: 
//https://stackoverflow.com/questions/3393854/get-and-set-a-single-cookie-with-node-js-http-server

 

두번째 방법은 npm 중 cookie 모듈을 다운받아 이용하는 것입니다.

terminal에서 npm install -s cookie를 치면 다운로드가 완료되는데, 이때부터는 간단하게

const cookie = require('cookie')만 치면 cookie에 접근이 가능합니다.

const http = require('http');
const fs = require('fs');
const url = require('url');
const qs = require('querystring');

// ⬇️ 새로 추가된 cookie 모듈 불러오기
const cookie = require('cookie');

const server = http.createServer((req, res) => {
  const {pathname} = url.parse(req.url);
  const {query} = url.parse(req.url);
  const {name, birth_date} = qs.parse(query);
  
  if (pathname === '/user'){
    let cookies = {};
  
    if (request.headers.cookie) {
      // ⬇️ request headers에 찍혀있는 cookie 파싱하기
      cookies = cookie.parse(req.headers.cookie);
    };
    
    /* 위처럼 코드를 작성해주어야 하는 이유는, 만일 쿠키가 아직 등록이 되어 있지 않은 상태라면
    TypeError: argument str must be a string 에러 메세지와 함께
    페이지는 작동하지 않게 됩니다.
    */
    
    res.writeHead(200, {
      'Set-Cookie' : 
      [
        `name = ${encodeURIComponent(name)}`, 
        `birth_date = ${birth_date}`
      ],
      'Content-Type':'text/plain; charset=utf-8'
    });

    console.log(cookies);
    //result: { 'user-info': 'testing', name: '불타는 키보드', 'birth_date': '2020-04-01' }

    res.end(`OK! We've received your profile.
    \nYour name : ${name}, 
    \nYour birthdate : ${birth_date}`);
  } else {
    fs.readFile('./server_content.html', (err, data) => {
      res.writeHead(200, {'Set-Cookie': 'user-info = testing'});
      res.end(data);
    });
  };
});
server.listen(8000);

콘솔 결과값을 보면 cookies는 객체를 출력합니다.

따라서 name 값이 필요로 하면 cookies.name, birthdate값이 필요로 하면 cookies.birth_date로 불러올 수 있습니다.

 

관련글 더보기

댓글 영역