ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2023 - 06 - 19 쿠키 (Cookie)와 세션 (Session)
    Today I Learned/TIL 06 2023. 6. 19. 14:13

    Node.js는 프로그래밍 언어가 아니라, 자바스크립트를 브라우저없이 단독으로 실행할 수 있는 하나의 플랫폼이다.

    npm은 node.js에서 오픈소스 라이브러리를 쉽게 사용하기 위해 개발된 '패키지 관리자' 형식의 프로그램이다.

    express는 서버가 아니라, 우리가 쉽게 서버 프로그램을 구성할 수 있게 만들어진 오픈소스 라이브러리 이다.

    HTTP는 우리가 일반적으로 데이터를 주고받을 때 사용하는 통신규약이다.

    웹 브라우저(익스프레스, 파이어폭스, 크롬 등)는 HTML로 이루어진 데이터를 읽어서 화면에 그려주는 역할을 한다.
    단순히 웹문서를 가져와 보여주는 것 뿐만 아니라, 여러가지 프로토콜 (http, ftp, file 등)을 지원하여 다른 웹서버에 데이터를 보낼수도 있다.


    -쿠키 (Cookie)

    쿠키는 웹브라우저에 구현된 기술중 하나. 사용자의 상태를 저장하기 위해 사용한다.

    서버에서 쿠키를 구워서 response(헤더)에 담아 보내면, 웹브라우저는 받은 데이터를 그대로 저장한다.

    브라우저는 만약 갖고있는 쿠키가 있다면, 서버에 request할때 항상 갖고있는 쿠키 데이터를 포함해서 보낸다.
    즉, 브라우저가 서버에 요청한 뒤 응답으로써 Set-Cookie 헤더를 받은 경우, 해당 데이터를 저장한 뒤 모든 요청에 포함해서 보낸다는 뜻.


    단, 쿠키 데이터는 별도의 암호화 없이 데이터를 그대로 주고받고, 여러 사이트에서 공유할수 있기 때문에 클라이언트에서 마음대로 조작하기 쉬워 보안에 취약하다.

    예를들어 Aste라는 도메인을 갖고 있고, Aste에서 발급되는 쿠키를 브라우저에서 갖고있다.
    브라우저가 쿠키 정보를 갖고있다가, Aste라는 도메인에 다시 접속하면, 즉 request를 하면
    자동적으로 현재 받은 쿠키 데이터를 request할때 자동 전달하게 된다.

    프론트엔드적으로 생각해봤을때, http에서는 이 쿠키를 프론트엔드가 자유자재로 사용할수 있다.
    https (시큐어)라고 좀더 http통신에 패킷을 암호화하는 프로토콜이 있다. 
    https에서는 이 쿠키를 자유자재로 가공을 못하는 특성이 있다.

     

    서버가 클라이언트HTTP 요청(Request)수신할 때, 서버응답(Response)과 함께 Set-Cookie 라는 헤더를 함께 전송할 수 있다. 그 후 쿠키는 해당 서버에 의해 만들어진 응답(Response)과 함께 Cookie HTTP 헤더안에 포함되어 전달받는다.

     

    Set-Cookie를 이용한 쿠키 할당하기

    app.get("/set-cookie", (req, res) => {
      let expire = new Date();
      expire.setMinutes(expire.getMinutes() + 60); // 만료 시간을 60분으로 설정합니다.
    
      res.writeHead(200, {
        'Set-Cookie': `name=sparta; Expires=${expire.toGMTString()}; HttpOnly; Path=/`,
      });
      return res.status(200).end();
    });
    
    
    
    Set-Cookie를 통해 writeHead에 전달한다
    
    getMinutes는 Date 매서드
    getMinutes() + 60;
    만료시간을 현재에서 60분뒤로 설정
    
    쿠키 데이터의 형태 (name = value), 세미콜론 기준으로 쿠키를 나눔
    세미콜론으로 쿠키의 속성값 지정도 가능
    
    Expires 만료기간 =>  toGMTString으로 설정한다.
    HttpOnly = http에서만 사용가능
    Path = path는 슬래시 / 로만 한다

     

     

    res.cookie()를 이용하여 쿠키 할당하기 (추천)

    app.get("/set-cookie", (req, res) => {
      let expires = new Date();
      expires.setMinutes(expires.getMinutes() + 60); // 만료 시간을 60분으로 설정합니다.
    
      res.cookie('name', 'sparta', {
        expires: expires
      });
      return res.status(200).end();
    });
    
    
    위에 expires라는 변수를 관리하는 것은 동일하지만, 밑에서 실제로
    쿠키를 설정하는 부분에서 간결하게 표현됨.
    name에는 name이라는 값을, value에는 sparta라는 값을 설정함
    expires 만료기간을 그냥 Date타입으로 작성해도 쿠키가 만들어짐

     

    이렇게 할당된 쿠키를 서버에서 갖고오는법

    클라이언트서버에 **요청(Request)**을 보낼 때 자신이 보유하고 있는 쿠키자동으로 서버에 전달하게 된다. 여기서 클라이언트가 전달하는 쿠키 정보는 Request header에 포함되어 서버에 전달된다.

    그렇다면 서버에서는 어떠한 방식으로 쿠키를 사용할 수 있을까요?

    일반적으로 쿠키는 req.headers.cookie에 들어있습니다. req.headers는 클라이언트가 요청한 Request헤더를 의미합니다.

     

    app.get("/get-cookie", (req, res) => {
      const cookie = req.headers.cookie;
      console.log(cookie); // name=sparta
      return res.status(200).json({ cookie });
    });
    
    
    reqest에서 header에서 쿠키 정보 보낸 사용자 확인

     

     




    -세션 (Session)


    세션은 쿠키의 특성을 이용한 기술이다. 쿠키는 클라이언트가 마음대로 데이터를 확인할수 있고,
    쿠키는 데이터를 통해 현재 상태를 주고받는 것이라면, 세션은 열쇠를 갖고있는것. 


    만약 서버에서 해당 사용자가 인증되었다고 하면, 인증된 사용자에 대한 자물쇠는 서버에 가지고있게 되고, 사용자에게는 자물쇠를 열수있게 되는 열쇠만 주게 된다. 사용자가 다시 서버에 호출할때 자물쇠를 열수있게 되는것. 


    실제로 서버에서 해당하는 사용자의 정보는 자물쇠가 갖고있으니까 자물쇠를 갖고나온 데이터를 서버에서 사용한다. 즉 좀더 안전하게 데이터를 관리할 수 있다.

    쿠키는 그 데이터 상태 자체를 쿠키에 저장한다.
    반면 세션은 데이터가 서버에 저장된다. 그리고 데이터마다 고유한 세션 ID가 만들어진다. 즉 서버에는 자물쇠가 할당되는것이고, 사용자에게는 열쇠가 할당되는 것이다.


    세션ID를 통해 쿠키를 주고받기 때문에, 세션 데이터에 접근가능한것은 서버이다. 서버는 자물쇠를 열어 갖고나온 데이터를 사용하게 되어있다. 좀 더 안정적으로 데이터관리가 된다.

    하지만 세션은 해당하는 열쇠로만 특정 데이터를 열 수 있다는 단점이 있다. 예를들어 사용자들에 엄청난 요청이 들어와서 사용자에 대한 정보를 확인해야 할 때  자물쇠를 열기 위해 데이터베이스 요청을 해서 갖고오거나, 레디스같은 캐시db 데이터를 갖고와서 호출한다거나 이런식으로 사용자의 정보가 모두 서버에서 관리되기 때문에 서버에 큰 부하가 걸렸을 때 세션을 어떻게 관리해야할지도 생각해야 한다.

    세션은 데이터를 서버에만 저장하기 때문에 보안이 좋으나, 반대로 사용자가 많은 경우 서버에 저장해야 할 데이터가 많아져서 서버 컴퓨터가 감당하지 못하는 문제가 생기기 쉽다.

     

    const express = require("express");
    const cookieParser = require("cookie-parser"); 
    const app = express();
    
    app.use(cookieParser()); // 쿠키 parser 미들웨어 전역객체
    // cookie-parser 미들웨어는 요청에 추가된 쿠키를 req.cookies 객체(obj형태)로 만들어준다.
    // 더이상 req.headers.cookie처럼 번거롭게 안 써도 됨.
    
    
    // set 쿠키, http://localhost:5002/set-cookie
    // 쿠키 할당 (서버가 클라이언트의 요청에 응답할 떄, `Set-Cookie` 라는 헤더를 함께 전송. 쿠키는 응답과 함께 cookie HTTP헤더안에 포함되어 클라이언트에게 전송)
    app.get("/set-cookie", (req, res) => {
        let expires = new Date();
        expires.setMinutes(expires.getMinutes() + 60); // 만료 시간을 60분으로 설정합니다.
      
        res.cookie('name', 'sparta', { //쿠키이름:name, 쿠키값(value):sparta
          expires: expires
        });
        return res.status(200).end();
      });
    
      
    // get 쿠키, http://localhost:5002/get-cookie
    // 쿠키 접근 (클라이언트가 서버에 요청할때 자신이 갖고있는 쿠키를 request헤더에 포함하여 자동으로 서버에 전달)
    app.get("/get-cookie", (req, res) => {
        const cookies = req.cookies;
        // const cookie = req.headers.cookie; => cookie 미들웨어를 사용하면 이렇게 안써도 됨
        console.log(cookies); // name=sparta
        return res.status(200).json({ cookies });
      });
    
    
    
    // set 세션, localhost:5002/set-session
    // 해당하는 쿠키를 사용자에게 전달할 때 sessionKey라는 이름으로 전달
    
    let session = {}; // 전역변수이자 빈 객체
    app.get('/set-session', (req, res) => {
      const name = 'sparta';
      const uniqueInt = Date.now(); // uniqueInt: 고유한 숫자값을 할당 (현재시간바탕으로 고유 숫자값), 사용자의 value로 지정됨
      session[uniqueInt] = name; // session 객체의 key값에 uniqueInt를 넣고 value에는 name이라는 변수에 할당된 값을 넣음 
    
      res.cookie('sessionKey', uniqueInt); // 'sessionKey'라는 이름으로, 실제 클라이언트가 사용할 수 있는 key값인 uniqueInt를 할당해준다
      return res.status(200).end();
    });
    
    // - 서버에 해당하는 유저의 정보를 저장하기 위한 `session`객체를 만들었다.
    // - `/set-session` API를 호출했을 때 `name=sparta`의 정보를 session에 삽입하고, 
    // 해당하는 데이터를 불러들이기 위한 시간 정보를 쿠키로 반환받는다.
    
    
    
    // get 세션, localhost:5002/set-session
    // 전달받은 sessionKey를 갖고, 서버에 저장된 세션안에 있는 결괏값을 사용자에게 제공
    app.get('/get-session', (req, res) => {
        const { sessionKey } = req.cookies; // 사용자의 cookies안에 있는 sessionKey 가져옴
        const sessionItem = session[sessionKey];   // session이라는 자물쇠를 sessionKey라는 열쇠로 연다.
        console.log(sessionItem);
        
        return res.status(200).json({ sessionItem : sessionItem });
      });
    
    // 쿠키에 저장된 sessionKey를 이용하여 session에 저장된 데이터를 불러온다.
    
    
    
    
    app.listen(5002, () => {
        console.log(5002, "포트로 서버가 실행되었습니다.");
    })




    -서버 프로그램
    서버 프로그램은 일반적으로 클라이언트에게 요청을 받아 응답해주는 프로그램의 유형 
    익스프레스를 통해 서버를 실행시킨것이 그 예. app.js를 통해 서버를 구현하고 서버를 실행하면
    그 자체가 서버 프로그램이다. 서버 컴퓨터는 서버 프로그램을 실행하고 있는 컴퓨터.

    AWS에 있는 EC2에 익스프레스 서버를 배포했을때, 여기서 서버 컴퓨터는 EC2이다.


    -REST API 
    = REST 아키텍쳐를 따라 구현된 API를 REST API라고 한다.
    REST는 Representational State Transfer의 줄임말로, URL, Headers, Method등 네트워크 표현 수단을 사람이 봐도 이해하기 쉬운 표현으로 정의하는 것이다.
    (REST는 월드 와이트 앱 (WWW)와 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍쳐의 한 형식이다)
    또한 이 REST 아키텍쳐는 사람이 봐도 쉽게 이해할 수 있도록 '자원'을 정의하고 이 '자원'을 중심으로 표현을 구성하는 원칙을 제시한다.



    -validation
    유효성 검사 같은 개념
    body또는 params에 들어온 데이터에 대해 검증하는 것
    ex)문자열 타입이 들어와야 할  곳에 숫자열이 들어오면 에러가 뜨게 하는 것

    댓글

Designed by Tistory.