쿠키, 세션, 토큰 + JWT

wannabeking·2022년 7월 12일
0

CS

목록 보기
10/27
post-thumbnail

쿠키(Cookie)란?

미용실에 재방문하면 "저번처럼 잘라드릴까요?"라고 묻는다.

  • 쿠키란 브라우저가 사용자의 정보를 저장하여 동일한 웹사이트에 재방문할 때 재사용하기 위한 목적으로 사용하는 텍스트 파일이다.
  • 서버에 요청 시 쿠키를 함께 전송하여 사용한다.
  • 쿠키는 브라우저별로 특정 폴더에 저장된다.
  • 만료일을 설정할 수 있다.
  • 쿠키의 구조는 다음과 같다.

    "key1"="value1", "key2"="value2"; ...
    path=/; expires=Sat, 02 Oct 2021 17:46:04 GMT;

  • 지속 쿠키와 세션 쿠키가 존재하며 방문한 웹사이트에서 생성, 사용되어 자사 쿠키라고 한다.
    • 지속 쿠키 : 브라우저 종료 후에도 남아 있다.
    • 세션 쿠키 : 브라우저를 종료하면 없어진다.
  • 특정 웹사이트에서 생성, 사용되지 않는 제 3자 쿠키도 존재한다.
    • 대부분 광고 목적으로 사용되며 추적 쿠키라고 부른다.
  • 보안 취약점이 존재하여 민감한 정보는 저장하지 않는 것이 좋다.
    • XSS(Cross-Site Scripting) : 스크립트를 삽입하여 사용자의 쿠키를 탈취할 수 있다. (HttpOnly로 http 통신 시에만 쿠키에 접근 가능하게 방어할 수 있음)
    • 스니핑(Sniffing) : 클라이언트 <-> 서버가 쿠키를 주고 받을 때 탈취할 수 있다.
    • 공용 PC에서 유출 : 공용 PC의 쿠키 파일을 탈취할 수 있다.


세션(Session)이란?

카페에 들어간 이후에는 "어서오세요. 주문 도와드리겠습니다."를 하지 않는다.

  • 세션이란 브라우저를 통해 웹사이트에 접속한 시점부터 브라우저를 종료하여 연결을 끝내는 시점까지 같은 사용자에게 오는 요청들을 하나의 상태로 유지하는 기술이다.
  • 서버에 요청 시 쿠키에 세션 ID를 담아 보내고 서버는 해당 세션ID를 확인하여 동일한 사용자임을 확인한다.
  • 만약 세션ID가 존재하지 않다면 서버는 세션ID를 생성하여 전송하고 클라이언트는 쿠키에 저장한다.
  • 브라우저를 완전히 종료하기 전까지 로그인이 유지되는 것이 쿠키와 세션을 활용한 것이다.
  • 자동 로그인 또한 쿠키와 세션을 활용한 것이다. 로그아웃 하면 쿠키를 삭제한다.
  • 서버에 저장되므로 쿠키보다 보안적으로 뛰어나지만 그만큼 서버에 부하를 주고 세션ID를 통해 데이터를 참조하는 과정에서 쿠키보다 시간이 더 걸린다.
    • 따라서 노출되도 되는 정보는 쿠키에, 민감 정보는 세션에 저장하는 것이 좋다.
  • 세션ID를 탈취하거나 무작위 추측 대입으로 공격이 가능하다.
    • 세션ID 탈취를 방어하기 위해 동일 IP만 접근 가능을 사용할 수 있다.
    • 세션ID 무작위 추측 대입을 방어하기 위해 충분히 큰 값, 추측 불가한 랜덤 생성, 일정 횟수 시도 시 사용자 잠금, 주기적 재생성 등을 사용할 수 있다.


토큰(Token)이란?

  • 토큰은 인증된 사용자에게 권한을 부여하는 것이다.
  • 권한을 부여받은 사용자는 허가된 요청을 서버에 수행할 수 있게 된다.
  • 토큰에는 액세스 토큰과 리프레시 토큰이 있다.
    • 액세스 토큰 : 인증된 사용자에게 부여되는 토큰으로 탈취되어 권한을 빼앗길 수 있기 때문에 짧은 유효기간을 가진다.
    • 리프레시 토큰 : 로그인 시 액세스 토큰과 함께 발행되는 토큰으로 액세스 토큰이 만료되었을 때 새로 발급해주는 열쇠가 된다. 만약 리프레시 토큰도 만료되었다면 사용자는 다시 로그인을 수행해야 한다. (보통 2주의 유효기간) 리프레시 토큰이 특정 만료기간 만큼 남았을 때 요청이 오면 새로 발급해준다.


JWT(JSON Web Token)란?

  • JSON을 특정 암호화 알고리즘으로 암호화 된 토큰으로 헤더, 페이로드, 시그니처로 구성되며 '.'으로 구분한다.
  • 개인 키를 가지고 있는 서버만이 정상적인 토큰인지 인증할 수 있다.
  • 헤더와 페이로드는 서버가 아니어도 복호화 가능하기 때문에 민감 정보를 담지 말아야 한다.
  • 헤더 : 토큰의 타입
  • 페이로드 : 사용자 권한 정보와 데이터 <- Claim이라고 부른다

    표준 스펙은 다음과 같다.
    iss : 토큰 발급자 (issuer)
    sub : 토큰 제목 (subject)
    aud : 토큰 대상자 (audience)
    exp : 토큰의 만료시간 (expiraton), NumericDate 형식(예: 1480849147370)
    nbf : Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념, NumericDate 형식, 이 날짜가 지나기 전까지는 토큰 처리 X
    iat : 토큰이 발급된 시간 (issued at), 이 값을 사용하여 토큰의 age 가 얼마나 되었는지 판단
    jti : JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용, 일회용 토큰에 유용

  • 시그니처 : 서버의 개인 키로만 복호화 가능하기 때문에 서버만 복호화 가능하다. 서버가 복호화한 다음 base64UrlEncode(header)가 JWT의 헤더와 동일한지, base64UrlEncode(payload)가JWT의 페이로드와 동일한지 검증한다.


profile
내일은 개발왕 😎

0개의 댓글