Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

옥수수, 기록

[Backend 인증/보안] Cookie와 Session 본문

카테고리 없음

[Backend 인증/보안] Cookie와 Session

ok-soosoo 2023. 1. 9. 21:34

Cookie의 배경

HTTP 요청은 stateless하지않나?

쇼핑몰사이트를 돌아다니며 상품을 장바구니에 담고 페이지를 돌아다녀도 장바구니가 유지되는 것은 쿠키 덕분이다.

Cookie란

어떤 웹사이트에 들어갔을 때 서버가 일방적으로 클라이언트에 전달하는 작은 데이터

  • 서버가 웹 브라우저에 정보를 저장하고 불러올 수 있는 수단
  • 해당 도메인에 대해 쿠키가 존재하면 웹 브라우저는 도메인에게 http 요청 시 쿠키를 함께 전달

Cookie 이용법

사용자 선호, 테마 등 장시간 보존해야하는 정보 저장에 적합

Cookie 전달 방법

쿠키가 클라이언트에 저장되고 자동으로 요청되는 화면

서버가 응답헤더에 Set-Cookie라는 프로퍼티(속성)에 쿠키의 이름, 값, 경로등을 저장

쿠키가 담긴 응답헤더를 받은 클라이언트는 응답헤더에 존재하는 Set-cookie를 확인

다음부터 서버에 보내는 매 요청시마다 쿠키의 이름과 값을 서버에 전송하게 된다.

서버가 쿠키를 저장하면 이후로는 해당 웹 사이트를 이용할 때 매 요청에 자동으로 쿠키가 함께 전송

Cookie Options

  • Domain=<domain-value>
    • www.google.com과 같은 서버에 접속할 수 있는 이름
    • 포트 및 서브 도메인 정보, 세부 경로를 포함하지 않는다
      • 서브 도메인 : www 같이 도메인 앞에 추가로 작성되는 부분
    • 서버의 요청의 도메인이 일치하는 경우 쿠키 전송
      • naver.com에서 받은 쿠키를 google.com에 전송하는 일 방지
  • Path=<path-value>
    • 세부 경로로써 서버가 라우팅할 때 사용하는 경로를 의미
    • 서버와 요청의 세부경로가 일치하는 경우 쿠키 전송
      • 설정된 경로를 포함하는 하위 경로로 요청을 해도 쿠키를 서버에 전송 가능
        • ex) Path:/users , 요청: /users/document 인 경우 쿠키 전송 가능
  • MaxAge or Expires
    • 쿠키의 유효기간 설정하는 옵션
      • Max-Age=<number> : 쿠키가 유효한 시간을 초 단위로 설정하는 옵션
      • Expires=<date> : MaxAge와 비슷하지만 언제까지 쿠키가 유효한지 날짜를 지정할 수 있음
      • 둘다 작성시 : Max-Age(우선) > Expires
    • ex) PC방에 가서 로그아웃을 안한 경우
      • 서버에서 쿠키에 MaxAge 혹은 Expires 옵션을 통해 유효 기간 지정
      • 일정 시간 후 자동 소멸!
  • HttpOnly
    • 클라이언트에서 DOM을 이용해 쿠키에 접근하는 것을 막아주는 옵션
    • 스크립트의 쿠키 접근 가능 여부 결정
      • true: JavaScript로 쿠키 접근 불가능
      • (명시되지 않은 경우 기본) false: document.cookie로 쿠키접근 가능
    • 쿠키는 <script>태그로 접근가능 → XSS 공격에 취약!
    • 민감한 정보나 개인 정보는 담지 않는 것이 좋다
    •  

  • Secure
    • 사용하는 프로토콜에 따른 쿠키의 전송 여부를 결정하는 옵션
    • HTTPS 프로토콜에서만 쿠키 전송 여부 결정
      • Secure 옵션에 true값을 할당 → HTTPS 프로토콜에서만 쿠키 전송 가능
  • SameSite
    • CORS 요청의 경우 옵션 및 메서드에 따라 쿠키 전송 여부 결정
    • CSRF 공격을 방지할 수 있음
      • CSRF(Cross Site Request Forgery) : site a가 site b에서 사용자가 인증되는 동안 강제적으로 site b에게 위조된(forgery) 요청을 하는 것
    • 옵션에 따른 서버의 쿠키 전송 여부
      • Lax
        • Cross-Origin 요청시 : GET 메서드 요청만 쿠키 전송 O
      • Strict
        • Cross-Origin 요청시 : 쿠키 전송 X
        • same-site : 쿠키 전송 O
      • None
        • 모든 메서드 요청에 대해 쿠키 전송 가능
        • sameSite=”none”옵션은 보안에 취약, Secure 쿠키 옵션이 필요

쿠키를 이용한 상태 유지

서버 →→→ 인증정보를 담은 쿠키전송 →→→ 클라이언트

클라이언트 →→→ 전달받은쿠키 & 요청전송 →→→ 클라이언트

하여 인터넷 연결을 Stateful 하게 유지할 수 있다.

하지만 기본적으로 쿠키는 오랜 시간 동안 유지될 수 있고 HttpOnly 옵션을 사용하지 않았다면 JavaScrip를 이용해 쿠키에 접근할 수 있으므로 쿠키에 민감한 정보를 담는 것은 위험

이러한 인증정보를 이용, 해커가 유저인척 서버에 요청을 보낸다면 서버는 누가 요청을 보낸 건지 의심하지 않고 이를 인증된 유저의 요청으로 취급

→ 개인정보같은 민감한 정보가 탈취된다면 2차 피해도 일어날 수 있다.

 

Session

앞서 배운 쿠키는 데이터를 클라이언트에 저장하는 방식이었지만 session은 서버에 저장하는 것

  • 서버와 Client 간 연결이 활성화된 상태를 말함
  • 서버가 Client에 유일하고 암호화된 ID를 부여
  • 중요 데이터는 서버에서 관리

Cookie & Session

설명 접속 상태 저장 경로 장점 단점

  설명 접속 상태 저장 경로 장점 단점
Cookie 쿠키는 그저 http의 stateless한 것을 보완해주는 도구 클라이언트 서버에 부담을 덜어줌 쿠키 그 자체는 인증이 아님
Session 접속 상태를 서버가 가짐(stateful) 접속 상태와 권한 부여를 위해 세션아이디를 쿠키로 전송 서버 신뢰할 수 있는 유저인지 서버에서 추가로 확인 가능 하나의 서버에서만 접속 상태를 가지므로 분산에 불리

로그인

1번 이후 서버에 요청 시 로그인 과정을 거칠 필요 없음

1 로그인 시도

2 정확한 아이디와 비밀번호를 입력했다면 서버는 일종의 저장소에 세션을 저장

주로 in-memory or 세션 스토어(redis 등과 같은 트랜잭션이 빠른 DB)에 저장

3 세션이 만들어지면 각 세션을 구분할 수 있는 세션 아이디 생성

4 클라이언트에 세션 성공을 증명할 수단으로 세션 아이디를 전달

5 쿠키를 통해 유효한 세션 아이디가 전달

6 세션 스토어에 해당 세션이 존재한다면

7 8 서버는 해당 요청에 접근 가능하다고 판단

🚨: 쿠키에 세션 아이디 정보가 없는 경우 서버는 해당 요청이 인증되지 않았음을 알려줌

로그아웃

세션 아이디가 담긴 쿠키를 클라이언트에 저장되어 있으며 서버는 세션을 저장하고 있음

서버는 세션 아이디로만 인증 여부 판단

로그아웃은 두 가지 작업을 해야한다.

  • 서버 : 세션 정보 삭제
  • 클라이언트 : 쿠키 갱신

🚨 서버는 클라이언트의 쿠키를 임의로 삭제할 수 없지만 set-cookie로 클라이언트에게 쿠키를 전송할 때 세션 아이디의 키값을 무효한 값으로 갱신할 수 있음

express-session

Node.js에는 이런 세션을 대신 관리해 주는 express-session이라는 모듈이 존재

express-session은 세션을 위한 미들웨어, express서버에서 쉽게 세션을 위한 공간을 다룰 수 있도록 만들어줌

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,
    },
  })
);

쿠키 옵션과 비슷해 보이지만 세션의 경우 secret 옵션의 비밀키를 이용해 암호화해 세션 id라는 것을 생성해 클라이언트에게 쿠키로 전송

쿠키로 전송된 세션 id는 이에 종속되는 고유한 세션 객체를 가지며 이는 서버에 저장

이 때 세션 객체는 유저별로 독립적으로 생성된 객체이므로 유저별로 각각 다른 데이터를 저장할 수 있음 → 클라이언트가 유저의 개인정보를 담지 않고도 서버가 클라이언트의 세션 id를 이용해 유저의 인증여부 판단 가능

세션 객체는 req.session으로 접근 가능

참조자료 : GitHub: express-session

Comments