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를 사용하기 전 대표적인 로그인 방식
- 클라이언트가 서버에 접속 시 세션 ID를 발급 받음
- 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있음
- 클라리언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 같이 서버에 전달해서 요청
- 서버는 세션 ID를 전달 받아서 별다른 작업없이 세션 ID로 세션에 있는 클라언트 정보를 가져와서 사용
- 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답
이러한 방법은 세션이라는 개념을 도입하여 사용자 인증에 필요한 디비 접근을 최소화 할 수 있지만
서버와 클라이언트 양측에서 다음과 같은 단점이 발생한다.
서버 - 로그인한 각 클라이언트마다 세션 ID를 발급하고 세션을 서버에서 가지고 있어야 하기 때문에 로그인한 클라이언트가 많아질수록 서버측 메모리 스토리지의 소모가 증가한다 (stateful). 또한 특정 서버에 로그인한 클라이언트는 그 서버에 저장된 세션으로 검증을 수행해야 하기 때문에 같은 요청을 처리할 수 있는 다른 서버에 접속하면 다시 로그인을 진행해야 한다.
클라이언트 - 로그인 후에 발급받은 세션 ID를 쿠키에 저장하는데 이 쿠키는 보안성이 취약하다. 요청마다 매번 클라이언트 정보를 모두 쿠키에 담아서 사용자 인증을 할 수도 있다. 이 방법은 서버가 세션을 저정하고 있을 필요가 없기 때문에 단점을 해결할 수 있으나 쿠키를 탈취 당했을 시 위험성이 엄청나고, 세션을 통한 디비 접근 최소화의 이점을 없앨 수도? 있다.
세션 하이재킹 - 만일 A 사용자의 HTTP 요청을 B 사용자(해커)가 가로챘다면 그 안에 들어있는 쿠키도 충분히 훔칠 수 있다. 그리고 B 사용자는 그 훔친 쿠키를 이용해 HTTP 요청을 보내면 서버의 세션저장소에서는 A 사용자로 오인해 정보를 잘못 뿌려주게 된다.
jwt는 토큰을 이용한 검증 방식으로 위 문제점들을 해결할 수 있다.
jwt를 이용한 로그인 방식
- 사용자 로그인
- 서버에서는 계정정보를 읽어 사용자를 확인 후, 사용자의 고유한 ID값을 부여한 후, 기타 정보와 함께 Payload에 작성
- JWT 토큰의 유효기간을 설정
- 암호화할 SECRET KEY를 이용해 ACCESS TOKEN을 발급
- 사용자는 Access Token을 받아 저장한 후, 인증이 필요한 요청마다 토큰을 헤더에 실어 보냄
- 서버에서는 해당 토큰의 Verify Signature를 SECRET KEY로 복호화한 후, 조작 여부, 유효기간을 확인
- 검증이 완료된다면, Payload를 디코딩하여 사용자의 ID에 맞는 데이터 조회
jwt를 이용하면 세션 방식에서의 단점인 세션용 스토리지 사용을 없앨 수 있고(stateless) 토큰을 사용하기 때문에 토큰 값만 알고 있다면 어떤 서버로 요청이 들어가던 상관이 없다. 또한 클라이언트측에서도 토큰을 이용하여 요청을 하기 때문에 쿠키를 사용함으로써 발생하는 취약점이 사라진다.
'develop > Backend -Java' 카테고리의 다른 글
비동기 처리를 위한 Webflux (with. FCM) (0) | 2023.12.09 |
---|---|
[spring] 에러 코드 관리 (0) | 2022.11.25 |
스프링 - jwt (0) | 2022.11.20 |
Java(eclips)에서 DB(postgresql) 서버로 - JDBC (0) | 2022.04.04 |