[S3U7] Cookie와 Session

Yeong·2023년 3월 7일
0

CS

목록 보기
8/12

🏷️Cookie란

  • 쿠키는 http프로토콜의 무상태성을 보완해주는 도구이다. (원래 보안 목적이 아님)
  • 쿠키는 서버에서 클라이언트에 영속성있는 데이터를 저장하는 방법이다.
  • 쿠키를 이용하는 것은 단순히 서버에서 클라이언트에 쿠키를 전송하는 것만 의미하지 않고 클라이언트에서 서버로 쿠키를 다시 전송하는 것도 포함된다.

🏷️쿠키 옵션

  1. Domain
    클라이언트에서는 쿠키의 도메인 옵션과 서버의 도메인이 일치해야만 쿠키를 전송할 수 있다.
  2. Path
    Path 옵션의 특징은 설정된 경로를 포함하는 하위 경로로 요청을 하더라도 쿠키를 서버에 전송할 수 있다. 즉 Path가 /users로 설정되어 있고, 요청하는 세부 경로가 /users/codestates 인 경우라면 쿠키 전송이 가능하다.
  3. MaxAge or Expires
    쿠키가 유효한 기간을 정하는 옵션(유효기간 설정하지 않으면 쿠키는 브라우저 닫으면 사라짐)
  • MaxAge: 쿠키가 유효한 시간을 초 단위로 설정하는 옵션
  • Expires: MaxAge와 비슷하지만 언제까지 쿠키가 유효한지 날짜를 지정
  1. Secure
    사용하는 프로토콜에 따른 쿠키의 전송 여부를 결정하는 옵션
    만약 Secure 옵션이 true로 설정된 경우 HTTPS를 이용하는 경우에만 쿠키를 전송할 수 있다.
    단, 도메인이 localhost 인 경우에는 HTTPS가 아니여도 쿠키 전송이 가능하다.
  2. HttpOnly
    자바스크립트로 브라우저의 쿠키에 접근이 가능한지 여부를 결정
    옵션을 명시하지 않는 경우에는 기본적으로 false로 지정되며 이 경우 document.cookie를 이용해 자바스크립트로 쿠키에 접근할 수 있어 쿠키가 탈취될 위험이 있으므로 거의 항상 true로 설정
  3. SameSite
    Cross-Origin 요청을 받은 경우, 요청에서 사용한 메소드와 해당 옵션의 조합을 기준으로 서버의 쿠키 전송 여부를 결정
  • Lax: Cross-Origin 요청이라면 GET 메소드에 대해서만 쿠키를 전송할 수 있다
  • Strict: Cross-Origin이 아닌 same-site 인 경우에만 쿠키를 전송 할 수 있다
  • None: Cross-Origin에 대해 가장 관대한 옵션으로 항상 쿠키를 보내줄 수 있다. 다만 쿠키 옵션 중 Secure 옵션이 필요하다.

🏷️쿠키로 로그인 구현


1. [클라이언트]로그인 버튼 클릭하면 서버로 로그인 요청
2. [서버] 요청 처리해 응답(쿠키 전달)
서버에서 쿠키를 만들어 클라이언트에 전송할 때는 res.cookie 메서드 사용한다
res.cookie 메서드는 전달인자로 쿠키 이름, 쿠키 값, 쿠키 옵션을 받습니다.

// 만들어줄 쿠키의 옵션
const cookiesOption = {
        domain: 'localhost',
        path: '/',
        httpOnly: true,
        sameSite: 'none',
        secure: true,
    };

    if (userInfo.id === undefined) {
        res.status(401).send('Not Authorized');
    } else if (checkedKeepLogin) { // 쿠키 유효기간 옵션
        // max-age 옵션으로 작성하는 경우
        cookiesOption.maxAge = 1000 * 60 * 30;
        // 단위는 ms(밀리세컨드 === 0.001초)이니 주의하세요! -> 이렇게 작성할 경우 30분동안 쿠키를 유지합니다.

        // expires 옵션으로 작성하는 경우에는, 이렇게 작성하시면 됩니다.
        // cookiesOption.expires = new Date(Date.now() + 1000 * 60 * 30);
        // 지금 시간 + 30분 후에 쿠키를 삭제한다는 의미입니다.

		// 쿠키 이름은 cookieId, 값은 userInfo.id, 옵션은 cookiesOption 헤더를 통해 클라이언트로 전달함 
        res.cookie('cookieId', userInfo.id, cookiesOption);
        res.redirect("/userinfo");
    } else {
        // 로그인을 유지하고 싶지 않은 경우, max-age 또는 expires 옵션을 작성하지 않은 상태 그대로 쿠키를 설정합니다. 이젠 브라우저에 쿠키가 있다면 따로 코드를 작성해주지 않아도 요청을 보낼 때마다 자동으로 서버로 전달됩니다.
        res.cookie('cookieId', userInfo.id, cookiesOption);
      // 서버의 /useinfo 엔드포인트로 이동(리다이렉트)
        res.redirect("/userinfo");
    }
  1. [클라이언트] 받은 응답으로 상태 업데이트
  2. [클라이언트] 로그인 완료 화면으로 렌더링
  3. [클라이언트] 로그아웃 버튼 클릭하면 서버로 로그아웃 요청
  4. [서버] 로그아웃 처리(쿠키삭제)
    쿠키 삭제할 때는 res.clearCookie 메서드를 사용한다.
    res.clearCookie의 인자는 쿠키 이름, 쿠키 옵션이다.
const cookiesOption = {
    domain: 'localhost',
    path: '/',
    httpOnly: true,
    sameSite: 'none',
    secure: true,
  }

res.status(205).clearCookie('cookieId', cookiesOption).send("logout")
  1. [클라이언트] 상태 비우기 및 다시 로그인 화면 렌더링

📖Session

🏷️Session이란

  • 사용자가 인증에 성공한 상태를 세션이라고 부른다.
  • 서버는 일종의 저장소에 세션을 저장한다. 세션이 만들어지면, 각 세션을 구분할 수 있는 세션 아이디도 만들어지는데, 보통 클라이언트에 세션 성공을 증명할 수단으로써 세션 아이디를 전달한다. 이때 쿠키에 서버에서 발급한 세션 아이디를 저장한다.
    다시 인증이 필요할 때 쿠키를 통해 유효한 세션 아이디가 서버에 전달되고, 세션 스토어에 해당 세션이 존재한다면 서버는 해당 요청에 접근 가능하다고 판단한다. 반대로 세션 스토어에 해당 세션 아이디가 없다면 서버는 해당 요청이 인증되지 않음을 알려준다.

express-session

Node.js에는 이런 세션을 대신 관리해 주는 express-session 이라는 모듈이 존재한다.
express-session은 세션을 위한 미들웨어로, express 서버에서 쉽게 세션을 위한 공간을 다룰 수 있도록 만들어준다.

express-session를 사용해 위와 같이 세션의 옵션을 지정할 수 있다.
쿠키 옵션과 비슷해 보이지만, 세션의 경우 secret 옵션의 비밀키를 이용해 암호화해 세션 id라는 것을 생성한다. 그리고 암호화한 세션 id를 클라이언트에게 쿠키로 전송한다.

쿠키로 전송된 세션 id는 이에 종속되는 고유한 세션 객체를 가지며 이는 서버에 저장된다. 이때 세션 객체는 유저별로 독립적으로 생성된 객체이므로 유저별로 각각 다른 데이터를 저장할 수 있다.

const express = require('express');
const session = require('express-session');

const app = express();

app.use(
  session({
    secret: '@codestates',
    resave: false,
    saveUninitialized: true,
    cookie: {
      domain: 'localhost',
      path: '/',
      maxAge: 24 * 6 * 60 * 10000,
      sameSite: 'none',
      httpOnly: false,
      secure: true,
    },
  })
);

🏷️세션으로 로그인 구현


쿠키를 사용해 로그인 구현하는 것과 비슷하나 실제 유저의 id를 사용하지 않고 유저의 id를 세션id로 저장해 사용한다.
req.session.sessionId = userInfo.id

profile
긍정적으로~✍️(◔◡◔)

0개의 댓글