탄생 배경
세션 방식은 서버에서 상태를 관리하기 때문에 트래픽이 많을 경우 서버에 부하가 많이 가고 분산 서버 환경에서
세션을 공유하기가 어려운 문제가 존재했다. JWT 토큰은 이런 문제를 극복하고자 탄생하게 되었다.
구조
헤더, 페이로드, 서명으로 이루어져 있으며 이를 구분하는 값은 마침표(.)로 되어있다.
헤더
- typ: 토큰의 타입을 정의
- alg: 해싱 알고리즘 정의한다. 어떠한 알고리즘을 사용했는지 알 수 있다.
페이로드
사용자 정의 값을 담을 수 있는 공간이다.
등록된 약속어들이 있으니 해당 키 값은 피해서 등록할 수 있도록 해야 한다.
- iss: 토급 발급자
- sub: 토큰 제목
- aud: 토큰 대상자
- exp: 토큰 만료 시간
- nbf: 토큰 활성화 날짜 지정된 날짜 이전까지 토큰이 활성화 되지 않는다
- iat: 토큰 발급 시간
- jti: 토큰 고유 식별자
서명
헤더와 페이로드를 base64로 인코딩 후 비밀키로 암호화하여 생성 된다.
장점
- 서버를 확장할때 별도 인프라 구축 비용이 들지 않는다.
- 페이로드에 필요한 정보를 담아 보낼 수 있다.
(아무나 복호화해서 볼 수 있기 때문에 민감한 정보는 넣지 않아야 한다.)
- 웹 서비스가 아닌 다른 플랫폼에 서비스를 확장하기 수월하다.
(모바일 네이티브 앱에 경우 세션 방식을 사용하지 않는다.)
단점
- 페이로드에 많은 데이터를 담을 경우 그 만큼 토큰에 길이가 길어지기 때문에 네트워크 부하가 발생할 수 있다.
- 토큰이 탈취가 될 경우 만료전까지 대처가 불가능하다.
패러다임의 변화
JWT 토큰은 본래 세션이 가지고 있는 단점을 극복하기 위해 탄생했지만 토큰이 탈취 당했을때 문제를 해결하기 위해 본래의 상태를 관리하지 않는 특성을 버리고 만료 시간을 짧게 잡은 액세스 토큰과 만료 시간을 길게 잡은 리프레시 토큰을 생성하여 상태를 관리하는 방법이 등장했다.
토큰 생성과 리프레시 토큰으로 액세스 토큰을 재발급 받는 과정
위에 과정을 코드로 확인해보면 다음과 같다.
1. 클라이언트에서 로그인 요청이 들어오면 아이디 비밀번호를 오브젝트로 받아 처리한다.
2. 저장소에서 사용자 정보를 조회하여 아이디, 비밀번호 검증을 진행한다.
3. 리프레시 토큰을 생성한다.
4. 액세스 토큰을 생성한다.
6~7. 리프레시 토큰을 저장소에 저장한다,
8. 리프레시 토큰과 액세스 토큰을 클라이언트로 전달하되 리프레시 토큰에 경우 body에 실어서 보내는것이 아니라 http only, secure 속성을 주어 쿠키로 구워준다. 이렇게 하는 이유는 자바스크립트에서 xss 공격을 회피하기 위해서이다.
위에 과정을 코드로 확인해보면 다음과 같다.
1. 프론트에서 info API 호출
2. AuthorizedUser 어노테이션에 의해 aop 동작하여 헤더에서 accessToken 을 검증
3. 만료된 토큰일 경우 UnauthorizedException 을 내려준다.
4. 프론트에서 401 에러가 발생했을때 accessToken 재발급 api를 호출하고 쿠키에 refreshToken을 가져온다.
5. refreshToken을 검증한다.
6~7. refreshToken이 저장소에 있는지 검증한다.
8. accessToken 을 생성하여 클라이언트로 내려준다.
아래는 클라이언트에서 만료된 액세스 토큰으로 요청 후 401 에러를 받았을때 토큰을 재발급 요청하는 과정이다.
예제 코드는 axios로 작성되었지만 ajax로 비슷한 방법으로 처리가 가능하다.
1. 사용자 정보 조회 api 호출
2. 액세스 토큰 만료로 401에러 응답
3. 액세스 토큰 재발급 api 호출
4. 사용자 정보 조회 api 재호출
'springboot' 카테고리의 다른 글
스프링부트 RestTemplate with axios, ajax 로 파일 다운로드 하기 (0) | 2023.08.27 |
---|---|
스프링부트 apache poi 이용하여 엑셀 작업하기 (0) | 2023.08.26 |
aop를 활용하여 request, response 로그 출력 (0) | 2023.08.04 |
3년차 웹 개발자에 스프링부트 아키텍처 고찰... (0) | 2023.05.29 |
spring boot + vue.js 환경 구성하기 (0) | 2023.01.24 |
댓글