-
[CS study] 2022.04.22CS 2022. 4. 23. 00:39
쿠키, 세션 그리고 JWT 정리
모의면접에서 JWT 리프레시 토큰에 대한 질문을 받고 분명 내가 사용했었으나 정의를 몰라 제대로 답하지 못했다. 다시 한번 정확히 정리!
쿠키와 세션을 사용하는 이유
HTTP 프로토콜의 특징 때문이다.
- Connectionless : 클라이언트와 서버가 요청과 응답을 한 번 주고받으면 연결을 끊어버리는 특징
- Stateless: 요청과 응답으로 인해 통신이 끝난다면 상태 정보를 유지하지 않는 특성 ( ex 메인 페이지에서 로그인을 하고 다른 페이지로 넘어가면 다시 로그인을 해야 함)
이런 이유로 쿠키, 세션 혹은 JWT 토큰을 이용하여 사용자 인증에 대한 정보를 유지할 수 있다.
Cookie & Session
저장 위치
- 쿠키: 클라이언트의 웹 브라우저가 저장하는 메모리 or 하드디스크
- 세션: 서버의 메모리에 저장
만료 시점
- 쿠키: 저장할 때 expires 속성을 정의해 무효화시키면 삭제될 날짜를 정할 수 있음
- 세션: 클라이언트가 로그아웃하거나, 설정 시간 동안 반응이 없으면 무효화되기 때문에 정확한 시점 알 수 없음
리소스
- 쿠키: 클라이언트에 저장되고 클라이언트의 메모리를 사용하기 때문에 서버 자원 사용하지 않음
- 세션: 세션은 서버에 저장되고, 서버 메모리로 로딩되기 때문에 세션이 생길 때마다 리소스를 차지함
용량 제한
- 쿠키: 클라이언트도 모르게 접속되는 사이트에 의하여 설정될 수 있기 때문에 쿠키로 인해 문제가 발생하는 걸 막고자 한 도메인당 20개, 하나의 쿠키 당 4KB로 제한해 둠
- 세션: 클라이언트가 접속하면 서버에 의해 생성되므로 개수나 용량 제한 없음
동작 방식
- 쿠키
- 클라이언트가 로그인 요청
- 서버에서 쿠기 생성 후 클라이언트로 전달
- 클라이언트가 서버로 요청을 보낼 때 쿠키를 전송
- 쿠키를 이용해 유저 인증을 진행
문제점: 사용자 인증에 대한 정보를 모두 클라이언트가 가지고 있게 되므로 http 요청을 탈취당할 경우 쿠키 자체를 탈취당해 사용자 정보를 모두 빼앗길 수 있다.
- 세션
- 서버에서는 클라이언트에게 고유한 세션 ID를 부여 세션 저장소에 저장한 후 클라이언트에게 발급
- 클라이언트는 서버에서 받은 세션 ID를 쿠키에 저장하게 되고 요청을 보낼 때마다 쿠키를 보냄
- 서버는 쿠키에 담겨있는 세션 ID와 세션 저장소에 있는 정보와 대조한 후 데이터를 가져옴
문제점: 세션도 하이재킹 공격이 가능하나 세션의 유효기간을 만들어 예방가능 세션 저장소를 서버에서 관리하기 때문에 사용자가 많아지면 서버에 걸리는 부하가 증가한다.
JWT(JSON Web Token)
JWT는 웹 표준(RFC 7519)으로 두 개체에서 JSON 객체를 사용하여 가볍고 자가 수용적인 방식으로 정보를 안정성 있게 전달해준다.
구성요소
- . 을 구분자로 3가지 문자열로 구성되어 있음
- aaaa.bbbbb.ccccc의 구조로 앞부터 헤더(header), 내용(payload), 서명(signature)으로 구성됨
헤더(header)
- typ와 alg 두 가지의 정보를 지니고 있음
- typ: 토큰의 타입 JWT
- alg: 해싱 알고리즘을 지정함 HAMC, SHA256, RSA 등 사용되며 토큰을 검증할 때 사용되는 서명 부분에서 사용됨
정보(payload)
- 토큰을 담을 점보가 들어있음
- 정보의 한 조각을 클레임(claim)이라고 부름 이는 name/ value의 한 쌍으로 이루어져 있음
- 클레임의 종류는 크게 세분류로 나누어짐
- 등록된(registered) 클레임들은 서비스에서 필요한 정보들이 아닌 토큰에 대한 정보를 담기 위하여 이름이 이미 정해진 클레임들 등록된 클레임의 사용은 모두 선택적(optional)이다.
- iss: 토큰 발급자 (issuer)
- sub: 토큰 제목 (subject)
- aud: 토큰 대상자 (audience)
- exp: 토큰의 만료시간 (expiration) 시간은 NumericData 형식으로 되어야 하며 현재 시간보다 이후로 설정되어야 함
- nbf: Not before을 뜻하며 토큰의 활성 날짜와 비슷한 개념 여기도 NumericData 형식 이 날짜가 지나기 전까지는 토큰이 처리되지 않음
- iat: 토큰이 발급된 시간 (issued at) 이 값을 사용하여 토큰의 age가 얼마나 되었는지 판단
- jti: JWT의 고유 식별자로써, 주로 중복적인 처리를 방지하기 위하여 사용 일회성 토큰에 사용하면 유용
- 공개(public) 클레임들은 충돌이 방지된(collision-resistant) 이름을 가지고 있어야 함 그래서 클레임 이름을 URL형식으로 지음
- 비공개(private) 클레임은 양 측간에 (보통 클라이언트 <-> 서버) 합의하에 사용되는 클레임 이름들 이름이 중복될 수 있으니 사용할 때 유의해야 함
- 등록된(registered) 클레임들은 서비스에서 필요한 정보들이 아닌 토큰에 대한 정보를 담기 위하여 이름이 이미 정해진 클레임들 등록된 클레임의 사용은 모두 선택적(optional)이다.
서명(signature)
- 서명은 헤더의 인코딩 값과 정보의 인코딩 값을 합친 후 주어진 비밀키로 해쉬를 하여 생성 base64 형태로 나타냄
Refresh Token
- Token의 유효기간이 짧으면 사용자 입장에서 자주 로그인을 해야 함 번거롭다.
- Token의 유효기간이 길면 제삼자에게 탈취당할 경우 보안에 취약하다. 그 점을 보안하기 위해 사용하게 됨
- Access Token의 유효기간이 만료되었을 때, Refresh Token이 새로 발급해주는 열쇠가 됨
- Access Token이 1시간 Refresh Token이 1주라고 가정
- 사용자는 Access Token으로 1시간 동안 API요청을 하다가 시간이 만료됨
- Refresh Token을 이용하여 새롭게 토큰을 발급해줌
- Refresh Token이 만료될 시 사용자는 새로 로그인해야 함
- 공격자는 Access Token을 탈취하더라도 유효기간이 지나면 사용할 수 없다.
- Refresh Token도 탈취당할 수 있으므로 적절한 유효기간 설정이 필요
'CS' 카테고리의 다른 글
[CS study] 2022.05.11 (0) 2022.05.12 [CS study] 2022.05.10 (0) 2022.05.10 [CS study] 2022.04.20 (1) 2022.04.20 [CS study] 2022.04.19 (2) 2022.04.19 [CS study] 2022.04.17 (3) 2022.04.17