[Node.js] 쿠키 생성, 읽기

2023. 7. 6. 20:48공부 중/Node.js

0. 참고자료

 

 

Node.js - 쿠키와 인증 - 생활코딩

수업소개 이 수업은 웹서버의 정보를 웹브라우저에 저장해서 개인화, 인증, 사용자 추적 등의 기능을 구현할 수 있도록 해주는 쿠키(cookie)를 알려드리는 수업입니다. 또 인증 기능을 구현하는

opentutorials.org

 

 


1. 쿠키?

 

쿠키는 사용자가 방문한 웹사이트에서 사용자의 브라우저에 전송하는 작은 텍스트 조각입니다. 쿠키가 있으면 웹사이트에서 사용자의 방문에 관한 정보를 기억하여 다음번에 사이트에 방문했을 때 번거로운 작업을 피하고 더 유용하게 사이트를 활용할 수 있습니다. 브라우저, 앱 또는 기기, 픽셀, 로컬 저장소를 식별하는 데 사용되는 고유 식별자 같은 기타 기술도 이 목적으로 사용될 수 있습니다…

쿠키의 등장은 웹의 개인화에 있어서 중요한 사건이다.

 

개인화의 대한 요구가 1994년 넷스케이프사의 론 몬툴리가 쿠키를 고안했다.

 

웹서버의 정보를 웹브라우저에 저장해서 개인화, 인증, 사용자 추적 등의 기능을 구현할 수 있다.

 

그 결과 사람마다 선택과 취향에 맞는 웹 페이지를 보여줄 수 있게 되었다.

 

쿠키는 주로 세 가지 목적을 위해 사용됩니다 :

  1. 세션 관리(Session management)
    : 서버에 저장해야 할 로그인, 장바구니, 게임 스코어 등의 정보 관리
  2. 개인화(Personalization)
    : 사용자 선호, 테마 등의 세팅
  3. 트래킹(Tracking)
    : 사용자 행동을 기록하고 분석하는 용도

 

출처 : https://policies.google.com/technologies/cookies?hl=ko

출처 : https://developer.mozilla.org/ko/docs/Web/HTTP/Cookies

 


2. 쿠키 생성

 

 

Cookie - HTTP | MDN

Cookie HTTP 요청 헤더는 Set-Cookie 헤더와 함께 서버에 의해 이전에 전송되어 저장된 HTTP cookies를 포함합니다.

developer.mozilla.org

쿠키는 웹 브라우저와 웹서버가 주고받는 정보이므로 HTTP 프로토콜에 속한다.

 

HTTP 요청을 수신할 때, 서버는 응답과 함께 [Set-Cookie] 헤더를 전송할 수 있습니다.

 

쿠키는 보통 브라우저에 의해 저장되며, 그 후 쿠키는 같은 서버에 의해 만들어진 요청(Request)들의 Cookie HTTP 헤더 안에 포함되어 전송됩니다.

 

response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);

위의 코드에서 세팅된 헤더는 response.writeHead()에 의해서 세팅된 헤더와 합쳐진다.

 

res.writeHead(200, {
    'Set-Cookie': 'myCookie=Hello, this is my Cookie',
    'Content-Type': 'text/html'
});
res.end('<h1>Cookie has been set</h1>');

처음부터 response.writeHead()를 사용해서 쿠키를 생성할 수 있다.

 

  • 'Content-Type': 'text/html' : 쿠키는 MIME 타입과는 관계없다. 응답 본문의 미디어 타입과는 독립적으로 작동한다. 꼭 html이 아니라도 된다. 여기서 res.end()의 내용이 html이라서 그렇다.

 

//다른 예시
var http = require('http');
http.createServer(function(request, response){
    response.writeHead(200, {
        'Set-Cookie':['yummy_cookie=choco', 'tasty_cookie=strawberry']
    });
    response.end('Cookie!!');
}).listen(3000);

Content-Type 없어도 됩니다.

 

처음 접속하면 쿠키가 생성된 것을 확인할 수 있다. 두 번째 접속에는 쿠키를 보내기도 하고 받기도 했다. 

 

새로 고침 할 때마다 웹 브라우저는 서버로 쿠키를 보낸다.

 

  • 주의!

Cookie 헤더는 선택적(optional)이고, 만약 브라우저의 사생활 보호 설정(privacy settings)이 쿠키를 block할 경우 생략될 수도 있습니다.

 


3. 쿠키 읽기

var http = require('http');

function parseCookies(cookieString) {
    let cookies = {};
    if (cookieString) {
        let itemStrings = cookieString.split('; ');
        itemStrings.forEach(item => {
            let parts = item.split('=');
            cookies[parts[0]] = parts[1];
        });
    }
    return cookies;
}

http.createServer(function(request, response){
    const cookies = parseCookies(request.headers.cookie);
    response.writeHead(200, { 'Content-Type': 'text/html' });
    response.end(`<h1>${cookies.yummy_cookie || 'No yummy_cookie found'}, ${cookies.tasty_cookie || 'No tasty_cookie found'}</h1>`);
    //response.writeHead(200, {
    //    'Set-Cookie':['yummy_cookie=choco', 'tasty_cookie=strawberry']
    //});
    //response.end('Cookie!!');
}).listen(3000);

 

const server = http.createServer((req, res) => {
    const cookies = parseCookies(req.headers.cookie);
    ...
    res.writeHead(200, { 'Content-Type': 'text/html' });
    res.end(`<h1>${cookies.myCookie || 'No cookie found'}</h1>`);
    ...

 

function parseCookies(cookieString) {
    let cookies = {};
    if (cookieString) {
        let itemStrings = cookieString.split('; ');
        itemStrings.forEach(item => {
            let parts = item.split('=');
            cookies[parts[0]] = parts[1];
        });
    }
    return cookies;
}

cookieString은 yummy_cookie=choco; tasty_cookie=strawberry의 문자열에 불과하다.

 

그래서 사용하기 쉽게 객체로 파싱해야 한다.

 

위와 같이 함수를 직접 작성해서 추가해도 되지만 npm에서 cookie라는 모듈을 설치해서 사용해도 된다.

 

 

cookie

HTTP server cookie parsing and serialization. Latest version: 0.5.0, last published: a year ago. Start using cookie in your project by running `npm i cookie`. There are 3730 other projects in the npm registry using cookie.

www.npmjs.com

$ npm install cookie
const cookie = require('cookie');
const cookies = cookie.parse(req.headers.cookie || '');

// 만약
// req.headers.cookie = 'foo=bar; equation=E%3Dmc%5E2'
// cookies = { foo: 'bar', equation: 'E=mc^2' }

쿠키가 없는 경우 (첫 번째 접속) req.headers.cookieundefined되어 에러가 발생한다.

 

에러 처리까지 고려해라.

 


4. Node.js에서 쿠키

 

  • 직접 쿠키를 파싱하는 예시
const http = require('http');

const server = http.createServer((req, res) => {
    const cookies = parseCookies(req.headers.cookie);

    if (req.url === '/set-cookie') {
        res.writeHead(200, {
            'Set-Cookie': 'myCookie=Hello, this is my Cookie',
            'Content-Type': 'text/html'
        });
        res.end('<h1>Cookie has been set</h1>');
    } else if (req.url === '/get-cookie') {
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.end(`<h1>${cookies.myCookie || 'No cookie found'}</h1>`);
    } else {
        res.writeHead(404, { 'Content-Type': 'text/html' });
        res.end('<h1>Page not found</h1>');
    }
});

function parseCookies(cookieString) {
    let cookies = {};
    if (cookieString) {
        let itemStrings = cookieString.split('; ');
        itemStrings.forEach(item => {
            let parts = item.split('=');
            cookies[parts[0]] = parts[1];
        });
    }
    return cookies;
}

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

 

  • cookie 모듈을 사용하는 예시
var cookie = require('cookie');
var escapeHtml = require('escape-html');
var http = require('http');
var url = require('url');

function onRequest(req, res) {
  // Parse the query string
  var query = url.parse(req.url, true, true).query;

  if (query && query.name) {
    // Set a new cookie with the name
    res.setHeader('Set-Cookie', cookie.serialize('name', String(query.name), {
      httpOnly: true,
      maxAge: 60 * 60 * 24 * 7 // 1 week
    }));

    // Redirect back after setting cookie
    res.statusCode = 302;
    res.setHeader('Location', req.headers.referer || '/');
    res.end();
    return;
  }

  // Parse the cookies on the request
  var cookies = cookie.parse(req.headers.cookie || '');

  // Get the visitor name set in the cookie
  var name = cookies.name;

  res.setHeader('Content-Type', 'text/html; charset=UTF-8');

  if (name) {
    res.write('<p>Welcome back, <b>' + escapeHtml(name) + '</b>!</p>');
  } else {
    res.write('<p>Hello, new visitor!</p>');
  }

  res.write('<form method="GET">');
  res.write('<input placeholder="enter your name" name="name"> <input type="submit" value="Set Name">');
  res.end('</form>');
}

http.createServer(onRequest).listen(3000);

 


5. express에서 쿠키

const express = require('express');
const cookieParser = require('cookie-parser');

const app = express();
app.use(cookieParser());

// 쿠키 생성 라우트
app.get('/set-cookie', (req, res) => {
  res.cookie('myCookie', 'Hello, this is my Cookie', { maxAge: 900000, httpOnly: true });
  res.send('Cookie has been set');
});

// 쿠키 읽기 라우트
app.get('/get-cookie', (req, res) => {
  if (req.cookies.myCookie) {
    res.send(req.cookies.myCookie);
  } else {
    res.send('No cookie found');
  }
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

expresscookie-parser를 사용하여 쿠키를 생성하고 읽는 간단한 서버다.

 

express에서는 cookie-parser를 사용하여 간단하게 쿠키를 생성하고 읽을 수 있다.

 


'공부 중 > Node.js' 카테고리의 다른 글

[Node.js] 쿠키 옵션  (0) 2023.07.07
[Node.js] 세션 쿠키, 영구 쿠키  (0) 2023.07.06
[Express] 보안  (0) 2023.07.05
[Express] 미들웨어와 라우터를 활용한 리팩터링  (0) 2023.07.05
[Express] 오류 처리  (0) 2023.07.05