develop/Backend -Java

jwt (json wep token)

reko_ 2022. 11. 20. 16:21

JWT

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA

 

jwt는 json wep token의 약자로 json 데이터를 안전하게 교환할 수 있는 방법의 표준이다. 이 데이터는 디지털으로 서명되기 때문에 신뢰성이 검증되어 있다.  - jwt.io

 

디지털 서명이란? - https://rekodo.tistory.com/62

 

전자서명과 디지털 서명

전자서명 전자서명이란 사이버 공간에서의 인감으로 사이버 공간의 수많은 위협, 문서 위변조로부터 프로그램의 제작자를 확인하고 증명하기 위한 전자 문서 서명이다. 오프라인 상황과 비교

rekodo.tistory.com

 

 

JWT를 이용한 로그인

 

jwt는 웹 서버와 클라이언트간 json 정보를 주고 받을 때 상호간 주고 받은 데이터의 송신자를 검증할 때 사용되는 것 같다. 위 글의 디지털 서명은 단발성으로 문서를 송수신하고 문서의 제작자를 확인하는데,

 

 

웹 서버는 한번 로그인한 클라이언트가 계속해서 자신의 정보를 조회하기 때문에 로그인 성공 시 서버에서 토큰이라는 것을 발급해주어 로그인한 클라이언트 자신의 정보를 조회할 때 서버에서 발급받은 토큰을 같이 보내면 서버에서 다시 그 토큰을 복호화 하여 정상적인 json값이 나오면 검증이 되었다고 보고 요청에 맞는 응답을 해주는 것 같다.

 

 

jwt를 사용하기 전 대표적인 로그인 방식

  1. 클라이언트가 서버에 접속 시 세션 ID를 발급 받음
  2. 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있음
  3. 클라리언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 같이 서버에 전달해서 요청
  4. 서버는 세션 ID를 전달 받아서 별다른 작업없이 세션 ID로 세션에 있는 클라언트 정보를 가져와서 사용
  5. 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답

 

이러한 방법은 세션이라는 개념을 도입하여 사용자 인증에 필요한 디비 접근을 최소화 할 수 있지만

서버와 클라이언트 양측에서 다음과 같은 단점이 발생한다.

 

서버 - 로그인한 각 클라이언트마다 세션 ID를 발급하고 세션을 서버에서 가지고 있어야 하기 때문에 로그인한 클라이언트가 많아질수록 서버측 메모리 스토리지의 소모가 증가한다 (stateful). 또한 특정 서버에 로그인한 클라이언트는 그 서버에 저장된 세션으로 검증을 수행해야 하기 때문에 같은 요청을 처리할 수 있는 다른 서버에 접속하면 다시 로그인을 진행해야 한다.

 

클라이언트 - 로그인 후에 발급받은 세션 ID를 쿠키에 저장하는데 이 쿠키는 보안성이 취약하다. 요청마다 매번 클라이언트 정보를 모두 쿠키에 담아서 사용자 인증을 할 수도 있다. 이 방법은 서버가 세션을 저정하고 있을 필요가 없기 때문에 단점을 해결할 수 있으나 쿠키를 탈취 당했을 시 위험성이 엄청나고, 세션을 통한 디비 접근 최소화의 이점을 없앨 수도? 있다.

 

세션 하이재킹 - 만일 A 사용자의 HTTP 요청을 B 사용자(해커)가 가로챘다면 그 안에 들어있는 쿠키도 충분히 훔칠 수 있다. 그리고 B 사용자는 그 훔친 쿠키를 이용해 HTTP 요청을 보내면 서버의 세션저장소에서는 A 사용자로 오인해 정보를 잘못 뿌려주게 된다.

 

jwt는 토큰을 이용한 검증 방식으로 위 문제점들을 해결할 수 있다.

 

 

jwt를 이용한 로그인 방식

  1. 사용자 로그인
  2. 서버에서는 계정정보를 읽어 사용자를 확인 후, 사용자의 고유한 ID값을 부여한 후, 기타 정보와 함께 Payload에 작성
  3. JWT 토큰의 유효기간을 설정
  4.  암호화할 SECRET KEY를 이용해 ACCESS TOKEN을 발급
  5. 사용자는 Access Token을 받아 저장한 후, 인증이 필요한 요청마다 토큰을 헤더에 실어 보냄
  6. 서버에서는 해당 토큰의 Verify Signature를 SECRET KEY로 복호화한 후, 조작 여부, 유효기간을 확인
  7. 검증이 완료된다면, Payload를 디코딩하여 사용자의 ID에 맞는 데이터 조회

 

jwt를 이용하면 세션 방식에서의 단점인 세션용 스토리지 사용을 없앨 수 있고(stateless) 토큰을 사용하기 때문에 토큰 값만 알고 있다면 어떤 서버로 요청이 들어가던 상관이 없다. 또한 클라이언트측에서도 토큰을 이용하여 요청을 하기 때문에 쿠키를 사용함으로써 발생하는 취약점이 사라진다.