티스토리 뷰

쿠키,세션과 JWT의 특징과 차이점을 알아보겠습니다.

 

 

 

 

1. HTTP 특성


쿠키와 세션, JWT를 이해하기 위해서는 먼저 HTTP의 비연결성 및 무상태성 이라는 특성을 알아야합니다.

 

[ 비연결성 (Connectionless) ]

클라이언트와 서버가 요청과 응답을 한 번 주고받으면 연결을 끊어버리는 특징

[ 무상태성(Stateless) ]

통신이 끝나고 연결이 끊어지면 서버에서는 클라이언트의 상태정보를 유지하지 않는 특징

 

 

만약 서버가 다수의 클라이언트와 연결을 계속 유지한다면, 이에 따른 자원 낭비가 심해집니다. 비연결성 및 무상태성의 특징을 가진다면 불필요한 자원 낭비를 줄일 수 있다는 장점이 있습니다.

그러나 서버는 클라이언트를 식별할 수 없다는 단점 또한 존재합니다. 로그인을 하더라도 다음 요청에서는 해당 클라이언트를 기억하지 못해, 또 로그인을 해야하는 문제가 발생합니다. 

하지만 우리가 사용하고 있는 웹 사이트들의 경우, 한 번 로그인 하면 다시 로그인할 필요 없이 여러 페이지를 돌아다니며 다양한 기능들을 이용할 수 있습니다. 심지어는 브라우저를 껐다 켜도 로그인이 유지가 되기도 합니다.

이는 HTTP의 비연결성 및 무상태성 특징을 보완한 기술인 Cookie와 Session 덕분입니다.

 

 

 

 

2. Cookie & Session


쿠키(cookie)와 세션(session)을 서로 대립하거나 세션이 쿠키를 대체하는 기술로 오해하는 일이 있지만, 사실 쿠키와 세션은 상호 보완을 하는 기술이라고 생각하는 것이 맞겠습니다. 쿠키의 단점인 브라우저에 저장되어 유실/변조/도난되기 쉬웠던 문제를 세션의 서버에서 저장/관리 된다는 장점과 상호 보완되어 사용되게 됩니다.세션을 사용한다해서 쿠키라는 정보 저장체자체를 주고 받는다는 사실은 크게 다르지는 않고, 유저정보라는 민감정보를 다뤄야하는 로그인과 같은 상황에서의 보완점을 찾기위해서 나온 것이 Session이기 때문입니다.

 유저정보를 주고받지말고 인증 정보자체를 세션 저장소에 저장하고, 이 값을 쿠키에 담아 클라이언트가 쿠키를 요청할 때마다 세션 저장소에 있는 정보랑 동일한지로 로그인을 확인하자가 주요 핵심입니다.

 

 

[ HTTP요청 ]
POST /login HTTP/1.1
Host: www.test.com
Content-Length: 27
Content-Type: application/x-www-form-urlencoded

username=test&password=1234

아이디와 패스워드를 입력하여 서버에 요청하면

 

 

[ HTTP응답 ]
HTTP/1.1 302 Found
Content-Type: text/html
Location: https://www.test.com/
Set-Cookie: sessionId=a2dd774e36e2

서버에서는 검증로직 후 세션을 생성하여 클라이언트 식별자인 SESSIONID를 쿠키에담아 클라이언트로 응답하게 됩니다.

 

 

[ HTTP요청 ]
GET / HTTP/1.1
Host: www.test.com
Cookie: sessionId=a2dd774e36e2

이후 브라우저는 매번 요청을 보낼 때 마다 이 세션 아이디가 담긴 쿠키를 서버로 돌려 보내게 되고, 서버는 SESSIONID 유효성을 판별해 클라이언트를 식별합니다.

 

 

2.1. 장단점

  • 쿠키를 포함한 요청이 외부에 노출되더라도 세션 ID 자체는 유의미한 개인정보를 담고 있지 않습니다.
  • 그러나 해커가 이를 중간에 탈취하여 클라이언트인척 위장할 수 있다는 한계가 존재합니다.
  • 각 사용자마다 고유한 세션 ID가 발급되기 때문에, 요청이 들어올 때마다 회원정보를 확인할 필요가 없습니다.
  • 그러나 사용자 요청마다 세션 저장소를 조회해야하는 단점이 있습니다.
  • 서버에서 세션 저장소를 사용하므로 요청이 많아지면 서버에 부하가 심해집니다.

 

 

 

 

3. JWT 기반 인증


JWT(JSON Web Token)란 인증에 필요한 정보들을 암호화시킨 토큰을 의미합니다. JWT 기반 인증은 쿠키/세션 방식과 유사하게 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별합니다. 세션을 사용하면서 단점으로 꼽히는 요청을 진행할 때마다 세션 저장소에 세션 ID를 조회 DB 접근 로직이 한번 더 수행된다는 점을 개선하기 위해 나온 기술입니다.

 

 

3.1. JWT 구조

JWT는 .을 구분자로 나누어지는 세 가지 문자열의 조합입니다. 실제 디코딩된 JWT는 다음과 같은 구조를 지닙니다.

 

 

[ Header ]

Header는 alg과 typ는 각각 정보를 암호화할 해싱 알고리즘 및 토큰의 타입을 지정합니다.

 

 

[ Payload ]

Payload는 토큰에 담을 정보를 지니고 있습니다. 주로 클라이언트의 고유 ID 값 및 유효 기간 등이 포함되는 영역입니다. key-value 형식으로 이루어진 한 쌍의 정보를 Claim이라고 칭합니다.

 

표준 스펙상 key의 이름은 3글자로 되어있고, JWT의 핵심 목표는 사용자에 대한, 토큰에 대한 표현을 압축하는 것이기 때문에 이를 정의한 것이라고 볼 수 있습니다.

 

  1. iss (Issuer) : 토큰 발급자
  2. sub (Subject) : 토큰 제목 - 토큰에서 사용자에 대한 식별값이 됨
  3. aud (Audience) : 토큰 대상자
  4. exp (Expiration Time) : 토큰 만료 시간
  5. nbf (Not Before) : 토큰 활성 날짜 (이 날짜 이전의 토큰은 활성화 되지 않음을 보장)
  6. iat (Issued At) : 토큰 발급 시간
  7. jti (JWT Id) : JWT 토큰 식별자 (issuer가 여러명일 때 이를 구분하기 위한 값)

 

 

[ Signature ]

Signature는 인코딩된 Header와 Payload를 더한 뒤 비밀키로 해싱하여 생성합니다. Header와 Payload는 단순히 인코딩된 값이기 때문에 제 3자가 복호화 및 조작할 수 있지만, Signature는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없습니다. 따라서 Signature는 토큰의 위변조 여부를 확인하는데 사용됩니다.

 

 

[ HTTP요청 ]
POST /login HTTP/1.1
Host: www.test.com
Content-Length: 27
Content-Type: application/x-www-form-urlencoded

username=test&password=1234

아이디와 패스워드를 입력하여 서버로 보내게 되면,

 

 

[ HTTP응답 ]
HTTP/1.1 302 Found
Content-Type: text/html
Location: https://www.test.com/
Authorization: <type> <access-token>

서버는 검증 후 클라이언트 고유 ID 등의 정보를 Payload에 담고, 암호화할 비밀키를 사용해 Access Token(JWT)을 발급, 응답 헤더 Authorization에 토큰을 포함시켜 응답하게 됩니다.

 

 

[ HTTP요청 ]
POST /login HTTP/1.1
Host: www.test.com
Content-Length: 27
Content-Type: application/x-www-form-urlencoded
Authorization: <type> <access-token>

클라이언트는 전달받은 토큰을 저장해두고, 서버에 요청할 때 마다 토큰을 요청 헤더 Authorization에 포함시켜 함께 전달합니다. 서버는 토큰의 Signature를 비밀키로 복호화한 다음, 위변조 여부 및 유효 기간 등을 확인합니다.

 

 

3.2. 장점

  1. Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있습니다.
  2. 인증 정보에 대한 별도의 저장소가 필요없습니다.
  3. JWT는 토큰에 대한 기본 정보와 전달할 정보 및 토큰이 검증됬음을 증명하는 서명 등 필요한 모든 정보를 자체적으로 지니고 있습니다.
  4. 클라이언트 인증 정보를 저장하는 세션과 다르게, 서버는 무상태가 됩니다.
  5. 확장성이 우수합니다.
  6. 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능합니다.
  7. OAuth의 경우 Facebook, Google 등 소셜 계정을 이용하여 다른 웹서비스에서도 로그인을 할 수 있습니다.
  8. 모바일 어플리케이션 환경에서도 잘 동작합니다.

3.3. 단점

  1. 쿠키/세션과 다르게 JWT는 토큰의 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해집니다.
  2. Payload 자체는 암호화되지 않기 때문에 유저의 중요한 정보는 담을 수 없습니다.
  3. 토큰을 탈취당하면 대처하기 어렵습니다.
  4. 토큰은 한 번 발급되면 유효기간이 만료될 때 까지 계속 사용이 가능하기 때문입니다.
  5. 특정 사용자의 접속을 강제로 만료하기 어렵지만, 쿠키/세션 기반 인증은 서버 쪽에서 쉽게 세션을 삭제할 수 있습니다.

 

4. 보안 전략


JWT 사용시 상기한 단점들을 극복하기 위해 다양한 전략을 채택할 수 있습니다. 각각의 전략은 장단점이 상이하기 때문에, 서비스의 특성을 고려하여 보안 수준을 높일지 사용자의 편의성을 높일지 결정해야 합니다.

 

4.1. 짧은 만료 기한 설정

토큰의 만료 시간을 짧게 설정하는 방법을 고려할 수 있습니다. 토큰이 탈취되더라도 빠르게 만료되기 때문에 피해를 최소화할 수 있습니다. 그러나 사용자가 자주 로그인해야 하는 불편함이 수반됩니다.

 

4.2. Sliding Session

글을 작성하는 도중 토큰이 만료가 된다면 Form Submit 요청을 보낼 때 작업이 정상적으로 처리되지 않고, 이전에 작성한 글이 날아가는 등의 불편함이 존재합니다. Sliding Session은 서비스를 지속적으로 이용하는 클라이언트에게 자동으로 토큰 만료 기한을 늘려주는 방법입니다. 글 작성 혹은 결제 등을 시작할 때 새로운 토큰을 발급해줄 수 있습니다. 이를 통해 사용자는 로그인을 자주 할 필요가 없어집니다.

 

4.3. Refresh Token

클라이언트가 로그인 요청을 보내면 서버는 Access Token 및 그보다 긴 만료 기간을 가진 Refresh Token을 발급하는 전략입니다. 클라이언트는 Access Token이 만료되었을 때 Refresh Token을 사용하여 Access Token의 재발급을 요청합니다. 서버는 DB에 저장된 Refresh Token과 비교하여 유효한 경우 새로운 Access Token을 발급하고, 만료된 경우 사용자에게 로그인을 요구합니다.

해당 전략을 사용하면 Access Token의 만료 기한을 짧게 설정할 수 있으며, 사용자가 자주 로그인할 필요가 없습니다. 또한 서버가 강제로 Refresh Token을 만료시킬 수 있습니다.

그러나 검증을 위해 서버는 Refresh Token을 별도의 storage에 저장해야 합니다. 이는 추가적인 I/O 작업이 발생함을 의미하기 때문에 JWT의 장점(I/O 작업이 필요 없는 빠른 인증 처리)을 완벽하게 누릴 수 없습니다. 클라이언트도 탈취 방지를 위해 Refresh Token을 보안이 유지되는 공간에 저장해야 합니다.

 

 

 

정리

현재 대부분의 서비스가 REST API를 사용하는 시점에서 Stateless한 방법을 사용하기 위해서는 어쩔 수 없이 지금과 같은 토큰의 방식의 인증 체계를 사용할 수 밖에 없기는 합니다. 쿠키는 보안상 문제가 너무 많고, 세션은 요청을 할 때마다 필수적으로 I/O작업이 일어나야 하고... JWT 조차도 Sliding Session을 사용하거나 Refresh Token을 사용해야하는 부수적인 요인이 존재 하기 때문에 적절하게 운영하려는 서비스 환경에 맞추어 어떠한 방식이 적합한가 고민해야겠습니다.

 

 

 

 

 

 

 

출처

'끄적끄적' 카테고리의 다른 글

[자료구조] 인덱스의 자료구조 (B-Tree)  (2) 2022.08.07
[인프라] 쉘이란?  (1) 2022.01.09
[학습방법] 질문 잘 하는 법  (0) 2021.11.02
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   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
글 보관함