Session, Cookie, Token

fe_sw·2022년 7월 28일
0

Security

목록 보기
1/2
post-thumbnail

쿠키, 세션, 토큰은 왜 등장했을까 ?

http 무상태 프로토콜이다 --> 즉, 통신 이후에 어떠한 연결도 남지 않는다(stateless)

결과적으로, 사용자는 각각의 HTTP통신에 자신을 알릴 수 있는 정보를 주어야 한다

'자신을 알릴 수 있는 정보'의 역할을 하는 것이 바로 쿠키/세션/토큰 이다.


HTTP의 일종으로 사용자가 어떠한 웹 사이트를 방문할 경우, 서버에서 사용자의 브라우저에 저장하는 작은 기록 정보 파일이다.

서버가 쿠키를 만들어 브라우저에게 보내고,브라우저에서 저장했다가 요청을 했을떄 다시 서버에 보내주는 문자열이다.

구성요소

  • 이름 : 각각의 쿠키를 구별하는데 사용되는 이름
  • 값 : 쿠키의 이름과 관련된 값
  • 유효시간 : 쿠키의 유지시간
  • 도메인 : 쿠키를 전송할 도메인(브라우저 도메인)
  • 경로 : 쿠키를 전송할 요청 경로

특징

  • 클라이언트에 총 300개의 쿠키를 저장할 수 있다.
  • 하나의 도메인 당 20개의 쿠키를 가질 수 있다.
  • 하나의 쿠키는 4KB(=4096byte)까지 저장 가능하다.
  • 브라우저에 저장되는 'key-value'쌍의 데이터 파일

동작방식

  1. 클라이언트가 HTTP Request 를 서버에게 보냄

  2. 서버에서 유효성(회원인지)확인 후,쿠키를 생성한뒤, HTTP Response 헤더에 쿠키 넣어 응답

  3. 클라이언트는 HTTP Response의 header에서 쿠키를 추출하여 저장

  4. 클라이언트가 Request하고 싶을 때, HTTP가 해당 쿠키를 찾아 header에 자동으로 넣어서 전송

생명주기

  • 만료기간에 따라 브라우저를 종료해도 계속해서 남아 있을 수 있다.
  • 세션쿠키(만료기간이 없는 쿠키)는 브라우저가 닫히면 삭제됨

Session

클라이이언트가 웹서버에 연결된 순간부터 웹 브라우저를 닫아 서버와의 통신을 끝낼 때 까지의 기간 이다. (서버가 클라이언트를 식별할 수 있도록 하는 방식자체를 의미)

서버에 세션에 대한 정보(세션 상태, 세션 데이터 등)를 저장해 놓고, 고유한 세션 ID를 쿠키에 저장해 클라이언트에 보내준다.

쿠키로만 인증수단을 가지면, 개발자도구열고 쿠키를 열어보면 누가 로그인했는지 알 수 있고, 데이터 조작도 가능하다.

따라서 직접적인 정보들을 암호화한 값이 세션이다.
중요한 정보는 서버에 저장하고,접근할 수 있는 세션키값만 브라우저에 저장한다.

구성요소

  • 이름 : 각각의 쿠키를 구별하는데 사용되는 이름
  • 값 : 쿠키의 이름과 관련된 값
  • 유효시간 : 쿠키의 유지시간
  • 도메인 : 쿠키를 전송할 도메인(브라우저 도메인)
  • 경로 : 쿠키를 전송할 요청 경로

특징

  • 클라이언트를 구분하기 위한 세션 ID를 발급
  • 쿠키에 넣어서 보내기 때문에 쿠키를 수단으로 사용
  • 브라우저가 종료되면 세션은 삭제
  • 클라이언트 수 만큼 서버에 저장되기 때문에 서버 부하의 문제가 있음

동작방식

  1. 클라이언트 HTTP Request를 서버에게 보냄

  2. 서버에서 유효성(회원인지)확인 후 고유한 Session-ID를 발급하여 쿠키에 넣고 HTTP Response header에 넣어 응답

  3. 클라이언트는 HTTP Response header에서 이 쿠키를 추출하여 저장

  4. 클라이언트가 HTTP Request를 보낼 때, HTTP가 해당 쿠키를 찾아 header에 자동으로 넣어서 전송

  5. 서버는 HTTP Request header에서 쿠키안에 Session-ID를 확인하고 통신

Cookie,Session 차이

저장위치

  • 쿠키 : 클라이언트(브라우저 or 디바이스)
  • 세션 : 서버

보안

  • 쿠키 : 클라이언트에 저장되므로 보안에 매우 취약
  • 세션 : 쿠키 내부에 Session-ID만 있기에, 직접적인 정보노출은 없다 ,그리고 서버에서 관리하므로 쿠키보다 비교적 보안성이 좋다

생명주기

  • 쿠키 : 만료시간 / 만료시간이 없다면 브라우저 종료해도 남아있음
  • 세션 : 료시간 / 브라우저 종료시 무조건 삭제

속도

  • 쿠키 : 클라이언트에 저장되어 있어서 서버 요청시 빠름
  • 세션 : 실제 저장된 정보가 있으므로 서버의 처리가 필요해 쿠키보다 느림

Cookie,Session 인증방식

쿠키를 통해 클라이언트 로그인 상태를 유지시킬 수 있었지만, 가장 큰 단점은 쿠키가 유출 및 조작 당할 위험이 존재한다는 것이다. 개인정보를 HTTP로 주고 받는 것은 위험하다

따라서 서버에서 사용자에 맞는 세션id와 유저정보를 세션저장소라는 별도의 저장소로 저장하고
쿠키를통해 세션아이디를 쿠키에 담아 브라우저에 저장한뒤 http 요청이 있을때마다 쿠키가 자동으

로 담기는데, 이때마다 서버는 쿠키에 담긴 세션아이디와 세션저장소에 저장된 세션아이디를 비교해 인증을 한다.

동작 방식

  1. 클라이언트 HTTP Request를 서버에게 보냄
  2. 서버에서 유효성(회원인지)확인 후 고유한 Session-ID를 발급하여 쿠키에 넣고 HTTP Response header에 넣어 응답
  3. 클라이언트는 HTTP Response header에서 이 쿠키를 추출하여 저장
  4. 클라이언트가 HTTP Request를 보낼 때, HTTP가 해당 쿠키를 찾아 header에 자동으로 넣어서 전송
  5. 서버는 HTTP Request header에서 쿠키안에 Session-ID를 확인하고 통신

단점

  1. 다중서버에서 환경에서 세션의 불일치 문제 발생
  2. 클라이언트 수 만큼 서버에 저장되기 때문에 서버 부하의 문제가 있음

stickey session(로드밸런서가 클라이언트 요청을 세션을 생성한 서버로만 전달),session clustering(모든 서버의 세션 동기화)등의 해결책이 있지만 확장성이 떨어진다는 문제는 여전하다.

Token

1.토큰은 서버의 상태를 저장하지 않음 (Stateless) -> 토큰 자체로 정보를 가지고 있어 별도의 저장소필요(세션마냥) X

2.Access Token 을 HTTP 헤더에 실어 서버에 전송

3.토큰은 임의로 생성된 비밀번호 같이 동작한다. 제한된 수명을 가지고, 새로운 토큰은 한번 만료되면 새로 생성(Refresh Token).

4.가장 많이 사용되는 JWT는 JSON 포맷으로 저장하는 web token이다. (JWT(JSON Web Token)는 인증에 필요한 정보들을 암호화시킨 토큰을 의미합니다.)

JWT구성요소

header: 토큰의 타입,해싱알고리즘
payload: 사용자정보
signature: header,payload를 합친 문자열을 서버의 비밀키와 함께 암호화 한것

동작방식

  1. 사용자가 로그인

  2. 서버에서는 계정 정보를 읽어 사용자를 확인 후, JWT 토큰의 유효기간을 설정
    암호화할 Secret key 를 이용해 Access Token 을 발급

  3. 클라이언트는 Access Token 을 받아 저장 후, 인증이 필요한 요청마다 토큰을 헤더에 실어 보냄

  4. 서버에서는 해당 토큰의 Verify Signature 를 Secret key 로 복호화한 후, 조작 여부, 유효기간을 확인

장점

간편하다: 세션/쿠키 인증은 별도의 저장소 관리가 필요(서버쪽 저장소를 말하는것), 토큰은 발급한 후, 검증만 하기 때문에 추가 저장소가 필요하지 않는다.

단점

1 .세션/쿠키 인증 방식은 쿠키가 악의적으로 이용될 경우 쿠키를 삭제하면 된다.
그러나 JWT 는 유효기간이 지나기 전까지 정보들을 이용할 수 있다.

이에 대한 해결책은, Access Token 유효기간을 짧게 하고 Refresh Token 이라는 새로운 토큰을 발급한다. 그렇게 되면 Access Token 을 탈취당해도 상대적으로 피해를 줄일 수 있다

  1. 쿠키,세션과 다르게 토큰 자체의 데이터 길이가 길다. 인증이 필요한 요청이 많아질수록 서버의 자원낭비가 발생한다.

3.payload는 암호화 되지 않기 때문에 유저의 중요한 정보를 담기 힘들다

Access Token + Refresh Token 인증방법


1.사용자가 ID , PW를 통해 로그인

2.서버에서는 회원 DB에서 값을 비교(보통 PW는 일반적으로 암호화해서 들어감)

3~4.로그인이 완료되면 Access Token, Refresh Token을 발급한다. 이때 일반적으로 회원DB에 Refresh Token을 저장

5.사용자는 Refresh Token은 안전한 저장소에 저장 후, Access Token을 헤더에 실어 요청을 보냄

6~7.Access Token을 검증하여 이에 맞는 데이터를 보냄

8.시간이 지나 Access Token이 만료됐다고 보냄

9.사용자는 이전과 동일하게 Access Token을 헤더에 실어 요청을 보냄

10~11.서버는 Access Token이 만료됨을 확인하고 권한없음을 신호로 보냄

12.사용자는 Refresh Token과 Access Token을 함께 서버로 보냄

13.서버는 받은 Access Token이 조작되지 않았는지 확인한후, Refresh Token과 사용자의 DB에 저장되어 있던 Refresh Token을 비교한다. Token이 동일하고 유효기간도 지나지 않았다면 새로운 Access Token을 발급

14.서버는 새로운 Access Token을 헤더에 실어 다시 API 요청을 진행

<Access Token 만료가 될 때마다 계속 과정 9~11을 거칠 필요는 없다. 사용자(프론트엔드)에서 Access Token의 Payload를 통해 유효기간을 알 수 있다. 따라서 프론트엔드 단에서 API 요청 전에 토큰이 만료됐다면 바로 재발급 요청을 할 수도 있다

0개의 댓글