보안 - 쿠키/Session

박채은·2023년 1월 15일
0

Spring

목록 보기
30/35

  Cookie  

서버가 클라이언트에게 전달하는 작은 데이터

  • HTTP의 stateless한 연결을 Stateful하게 만들어 준다.

쿠키의 이용

  • 서버에서 클라이언트에 데이터를 저장한다.
  • 서버는 쿠키를 이용해서 클라이언트의 데이터를 가져올 수 있다.

ex) 장바구니, 로그인 상태 유지, 테마 등

쿠키 옵션

1. Domain

  • URL이 http://www.localhost.com:3000/users/login 이라 하면, Domain은 localhost.com이다.
  • 도메인은 포트 및 서브 도메인 정보, 세부 경로를 포함하지 않는다.
    • 서브 도메인: www
    • 세부 경로: /users/login
    • 포트: 3000

2. Path

  • URL이 http://www.localhost.com:3000/users/login 이라면, Path는 /users이 된다.

3. MaxAge/Expires

  • 쿠키의 유효한 기간을 설정하는 옵션
    • Maxage: 몇 초동안 유효한지 설정
    • Expires: 어느 날짜/시간까지 유효한지 설정
  • 세션 쿠키: MaxAge 또는 Expires 옵션이 없는 쿠키
    -> 브라우저가 종료될 때, 쿠키가 사라짐
  • 영속성 쿠키: 설정한 옵션만큼 사용이 가능한 쿠키

4. Secure

  • Secure = true이면, HTTPS 프로토콜 을 이용하는 경우에만 쿠키를 전송할 수 있다.

5. HttpOnly

  • HttpOnly = true이면, 자바스크립트의 <script> 태그로 쿠키에 접근할 수 없다.

6. sameSite

sameSite를 설명하려면, Origin에 대해서 알아야한다.

✔️ Origin이란?

Origin은 출처로, URL의 프로토콜, 도메인, 포트를 말한다.
어떤 URL이 같은 출처인지 판단하려면 이 3가지가 모두 같은지 확인하면 된다.

[이미지 출처] https://hudi.blog/sop-and-cors/

✔️ 동일 출처 정책(SOP)이란?

동일한 출처 사이에만 리소스를 공유할 수 있다는 규칙

과거에는 서버 사이드 랜더링(SSR)을 통해서 서버가 클라이언트에게 HTML 파일을 만들어서 전달했다.
그렇기 때문에 모든 처리가 같은 도메인 내에서 일어난다.
굳이 다른 오리진으로 요청을 보낼 필요가 없기 때문에 동일 출처 정책으로 이를 막아둔 것이다.

✔️ 교차 출처 리소스 공유 (Cross-Origin Resource Sharing, CORS)

프론트단에서 API를 호출하는 등 다른 오리진으로 요청을 보내야 할 때가 많아졌다.
이러한 배경으로 SOP가 아닌 CORS가 등장했고, CORS는 리소스 호출이 허용된 출처를 서버가 명시해놓으면, 출처가 다르더라도 요청과 응답을 주고 받을 수 있도록 만들어놓은 정책이다.

  • same-site: 요청을 보낸 Origin = 서버의 도메인, 프로토콜, 포트인 경우 (출처 동일)
  • cross-origin: 요청을 보낸 Origin != 서버의 도메인, 프로토콜, 포트인 경우 (출처 비동일)

✔️ sameSite의 옵션

  • Lax: cross-origin일 때는 GET 메서드인 경우에만 쿠키를 전송할 수 있다.
  • Strict: same-site인 경우에만 쿠키를 전송할 수 있다.
  • None: HTTPS 프로토콜을 사용한다면, 항상 쿠키를 전송할 수 있다.(무조건 Secure = true 옵션이 필요함)

  Session  

서버와 클라이언트 간의 연결이 활성화된 상태
사용자가 인증에 성공한 상태

사용자가 정확한 아이디와 비밀번호를 입력하면(로그인), 서버는 인증에 성공했다고 판단한다.
서버가 "인증에 성공했음"을 알고 있다면, 유저는 해당 홈페이지를 사용하는 동안 매번 로그인할 필요는 없다.

이때 사용자가 "인증에 성공한 상태"세션이라고 부르고, 각 세션을 구분할 수 있는 세션 아이디가 만들어진다.

[이미지 출처] https://jiwoochoi.tistory.com/219

  • 서버가 클라이언트에게 유일하고 암호화된 ID(Session ID)를 부여한다.
    → 이 세션 ID로 어떤 클라이언트인지 구별할 수 있다.

  • Session은 서버에서 관리한다. -> 세션 저장소에 저장

  • 쿠키를 통해 Session ID를 발급한다.

    • (5)번에서 Set-Cookie로 Session ID를 담아서 클라이언트에게 전달한다.
    • 쿠키는 노출될 위험성이 크기 때문에, Session ID는 암호화되어야 한다.
  • 쿠키를 통해 Session ID를 가져온다.

    • (6)번에서 쿠키를 통해 세션 아이디를 가져오고, 세션 저장소에서 해당 세션이 존재하는지 확인한다.
    • 존재한다면, 서버는 해당 요청을 접근 가능하다고 판단하고 인증이 완료된다.

서버는 Session ID 로만 인증 여부를 판단한다.

1) 서버는 사용자가 인증에 성공했음을 알고 있어야 한다.
→ 서버는 세션(접속 상태)을 저장하고 있음
2) 클라이언트는 인증 성공을 증명할 수단을 갖고 있어야 한다.
→ 클라이언트는 Session ID가 담긴 쿠키를 저장하고 있음


로그아웃

로그아웃을 하려면, 서버는 저장되어 있던 세션 정보를 삭제해야하고, 클라이언트는 Session ID를 삭제해야 한다.

하지만 서버가 클라이언트의 Session ID를 임의로 삭제할 수 없기 때문에, Set-Cookie로 세션 아이디를 무효한 값으로 갱신시켜 줘야 한다.

1) 서버: 세션 정보를 삭제
2) 클라이언트: Set-Cookie를 통해, 쿠키를 갱신(세션 아이디도 갱신됨)


정리

  • 쿠키
    • HTTP의 stateless를 보완해주는 도구
      → 서버의 부담을 덜어줌
    • 클라이언트에 쿠키가 저장됨
    • 쿠키는 인증을 도와주지만, 인증 그 자체는 아님!
  • 세션
    • 서버에 세션이 저장됨
    • 세션 아이디가 인증의 역할을 한다.(신분증 같은 역할)

[참고]

https://hudi.blog/sop-and-cors/
https://jiwoochoi.tistory.com/219

0개의 댓글