JWT로 인증/인가하는 방법의 장단점과 ‘왜’ 쿠키/세션이 아닌 JWT로 인증/인가를 해야하는지에 대해

mj·2025년 1월 16일
0

ktb

목록 보기
22/27
post-thumbnail

👉 주제

  • JWT로 인증/인가하는 방법의 장단점
  • ‘왜’ 쿠키/세션이 아닌 JWT로 인증/인가를 해야하는지

위의 주제를 알아보기 전, 먼저 JWT쿠키/세션에 대해 간단히 알아보자.

JWT와 쿠키/세션 간의 기본적인 차이

쿠키/세션


이미지출처 : https://medium.com/@alysachan830/cookie-and-session-ii-how-session-works-in-express-session-7e08d102deb8

쿠키/세션 인증 방식

  1. 유저가 웹사이트에서 로그인하면, 서버는 세션ID를 생성한다. 세션ID를 key로 사용해 key-value형태로 사용자의 정보를 세션저장소에 저장한다.
  2. 서버는 세션ID를 쿠키에 저장해 클라이언트에 전달한다.
  3. 클라이언트는 요청 시마다 세션 ID를 쿠키에 담아 서버에 보낸다.
  4. 서버는 사용자가 보낸 요청 쿠키의 세션ID를 기반으로 세션 저장소에서 사용자정보(value)를 찾아 확인한다.



JWT (Json Web Token)


JWT란 인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미

  • 서버에 저장소가 필요 없다.
  • 사용자가 로그인하면 서버는 JWT를 생성해 클라이언트에 전달. 이 JWT에는 사용자 정보와 유효 기간 등이 포함돼 있다.
  • 클라이언트는 요청 시마다 JWT를 서버에 보내고, 서버는 이 토큰을 검증해 사용자를 식별해.
    Header: { "alg": "HS256", "typ": "JWT" }
    Payload: { "id": 123, "role": "user", "exp": 16725000 }
    Signature: Header와 Payload를 secret key로 암호화
    • 이 JWT를 클라이언트가 Authorization 헤더나 쿠키에 담아 요청.

JWT 인증 과정

이미지출처 : https://inpa.tistory.com/entry/WEB-📚-JWTjson-web-token-란-💯-정리

JWT의 구조

1. 헤더 Header

{
 "alg" : "HS256",
 "typ" : "JWT"
}
  • alog: 서명 암호화 알고리즘
  • typ: 토큰유형

2. 내용 Payload

서버와 클라이언트가 주고받는 시스템에서 실제로 사용될 정보에 대한 내용을 담고 있다.

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": "1516239022"
}

3. 서명 Signature

토큰이 위조되지 않았음을 확인하는 역할.
서명이 유효해야만 서버가 요청을 처리하거나 허락할 수 있다.

시그니처(signature)의 구조

: ( 헤더 + 페이로드 + 서버가 갖고있는 유일한 key값=비밀키 )을 헤더에서 정의한 알고리즘으로 암호화한 값


JWT가 토큰 인증 신뢰성을 가지는 이유

정상적인 JWT

A(Header) + B(Payload) + C(Signature)

공격자가 Payload를 수정한 경우

A + B'(수정된 Payload) + C(기존 Signature)

서버에서 JWT를 검증하는 과정

클라이언트가 서버로 보낸 JWT
정상적인 JWT는 A(Header) + B(Payload) + C(Signature) 이지만, 중간에 공격자가 Payload를 수정하여 아래와 같이 변경된채로 서버에게 보내졌다.

A + B' + C

서버측에서 검증

서버는 클라이언트가 보낸 Signature(C)와 자신이 새로 생성한 Signature(C')를 비교한다.
만약 C ≠ C'라면, 토큰이 위조되었다고 판단한다.

C' = HMAC_SHA256(A + B', Secret Key)


이미지출처 : https://inpa.tistory.com/entry/WEB-📚-JWTjson-web-token-란-💯-정리

Signature(C)는 원래 Header(A)와 공격자가 수정하기 이전의 Payload(B)를 기반으로 생성된 값이다.
반면, 서버에서 검증을 위해 새로 생성한 Signature(C')는 Header(A)와 수정된 Payload(B')를 기반으로 생성된 값이기에 기존의 Signature(C)와는 일치하지 않게된다. C ≠ C
이경우 토큰이 검증되지 않았다고(위조되었다고) 판단하고 클라이언트의 요청을 처리하지 않게된다.


JWT은 서명(인증)이 목적이다

JWT는 Base64로 암호화를 하기 때문에 디버거를 사용한다면 복호화가 가능하다. 복호화하면 사용자의 데이터를 담은 Payload부분이 그대로 공개(노출)되어 버린다. 그렇기에 Payload에는 사용자의 노출되어서는 안되는 중요한 정보를 담으면 안된다.

정보보호도 안된다면 "JWT는 왜 사용하는것일까?"라고 생각할 수 있다.
하지만 토큰의 진짜 목적은 정보 보호가 아닌, 위조 방지이다.
토큰 안에 어떤 정보가 들어있는지가 중요한것이 아니라 해당 토큰이 유효한 토큰인지를 확인하는 것이 중요한 것이다.


왜 JWT 를 선택해야할까? (JWT의 장점)

1. 확장성과 서버 부담

  • 쿠키/세션:
    • 세션 저장소를 서버에 유지해야 해서, 사용자가 많아질수록 저장소 관리가 복잡해져.
    • 특히 서버가 여러 대로 늘어나면, 세션 동기화 문제가 생길 수 있어.
  • JWT:
    • 토큰 자체에 정보를 담기 때문에 서버 저장소가 필요 없어.
    • 서버 간 동기화가 필요하지 않아, 확장성이 뛰어나.

2. 분산 시스템에 적합

  • 쿠키/세션:
    • 세션 데이터는 특정 서버에 저장돼 있어서, 요청이 다른 서버로 가면 인증이 실패할 수 있어.
    • 이를 해결하려면 모든 서버가 동일한 세션 저장소를 공유해야 해.
  • JWT:
    • 클라이언트가 토큰을 직접 보내고, 서버는 그 토큰만 검증하면 돼. 어떤 서버로 요청이 가든 문제가 없어.

3. 다른 클라이언트에서도 사용 가능

  • JWT:
    • 웹 브라우저뿐만 아니라 모바일 앱, IoT 기기 등에서도 사용할 수 있어.
    • 클라이언트가 토큰만 가지고 있다면, HTTP 요청만으로 인증이 가능하니까!
      (쿠키/세션은 브라우저에 최적화된 도구. 앱에서는 브라우저처럼 자동으로 세션ID를 쿠키에 담아 요청을 보내지 못한다고 한다. 직접 수동으로 코드를 작성해주어야 하기에 번거로움)

JWT의 단점

  1. 네트워크 부하
    • 쿠키/세션에 비해 토큰의 길이가 길어, 인증 요청이 많아질수록 부하가 심해진다.
  2. 보안 문제:
    • JWT은 누구나 열람이 가능하기에 민감한 사용자 정보를 토큰에 그대로 저장하면 안 된다.
    • JWT에는 사용자 정보가 포함돼 있어서, 탈취되면 악용될 가능성이 있다.
  3. 무효화 어려움:
    • JWT는 서버에서 저장하지 않기 때문에, 유효 기간이 끝나기 전까지 무효화가 어렵다.
    • 반면, 세션은 서버에서 직접 삭제하면 끝난다.

JWT vs 쿠키/세션, 어떤 상황에서 선택할까?

  • JWT를 사용해야 할 때:
    • 서버 간 확장성이 중요하거나, 분산 시스템을 사용하는 경우.
    • 다양한 클라이언트(웹, 모바일, IoT)에서 인증이 필요한 경우.
  • 쿠키/세션을 사용해야 할 때:
    • 보안이 최우선이고, 세션 관리를 직접 제어하고 싶은 경우.
    • 시스템 규모가 작고, 서버 부하가 크지 않을 경우.




참고)
https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-JWTjson-web-token-%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC

profile
일단 할 수 있는걸 하자.

0개의 댓글

관련 채용 정보