JWT 이란?
- JWT(JSON Web Token): URL로 이용할 수 있는 문자로만 구성된 JSON형식의 토큰 형태로 주로 클라이언트-서버간 인증 및 정보 교환에 사용됨
JWT의 구성요소
1. header(헤더): 토큰의 유형과 서명 생성에 어떤 알고리즘이 사용되었는지 정의
2. payload(내용): 사용자의 인증 정보를 담고 있으며, 정보의 한 조각을 '클레임'이라고 부름. 클레임은 name-vlaue의 쌍으로 이루어져 있으며, 토큰에 여러개의 클레임들을 넣을 수 있음(사용자 ID, 권한 등)
3. signature(서명): header와 payload를 비밀키로 서명한 값으로, 토큰이 변조되지 않았음을 검증하고 인증해주는 부분
Access Token과 Refresh Token의 관리방식
- JWT 방식은 결국 유저의 정보와 권한을 담고 있는 토큰을 주고 받는 형태기에, 탈취되었을 때 보안 문제가 생길 수 있음. 게다가Access Token과 Refresh Token은 각각의 취약점이 있어 저장소의 위치와 관리 방법이 중요함
1. Access Token
- 서버와 인증, 인가 요청을 주고 받는 주요한 토큰. acess token의 주요 저장소로 아래 3가지가 있음
1-1. local storage
- 페이지 새로고침 및 브라우저를 여닫아도 인증 상태가 유지되지만, XSS 공격에 취약함
1-2. session storage
- 페이지 종료시 토큰이 사라져 사용하지 않는 동안의 보안의 위협은 감소하지만, 사용 중에 있어서 여전히 XSS 공격에 취약하며 새로고침시 로그인이 해제되는 불편함이 있을 수 있음
1-3. 메모리
- zustand, tanstack query, context api 등의 전역 상태로 관리하는 방법. 메모리를 사용하기에 XSS 공격에 비교적 안전하지만, 새로고침 시 데이터를 유지하기 어려움
=> 가장 안전한 장소로 꼽을 만한 곳이 존재하지 않으며, 새로고침 시 데이터 유지를 시킬 수 있는 local storage에 저장하는 편이다. 그 보완책으로 Access Token의 유효시간을 짧게 설정하여 토큰 탈취에 대비함
2. Refresh Token
- Access Token의 수명이 짧기 때문에 토큰이 만료될 경우 다시 발급 받을 수 있도록 Refresh Token을 함께 사용한다. Accces Token이 만료될 경우 Refresh Token으로 서버에서 다시 Access Token을 발급받는데 사용되며, 유효기간이 짧은 Access Token과 비교해 긴 수명을 가지고 있다. Refresh Token은 서버에서 발급받고, 서버에서 관리되기에 탈취될 위협이 있다면 토큰을 강제로 사용하지 못하게 하는 방법을 사용한다.
2-1. local/session storage
- Refresh Token은 Access Token을 무한정 발급시킬 수 있는 토큰으로 더 보완에 신경써야 함. 때문에 XSS 취약점을 가지는 로컬/세션 스토리지에 저장하기는 위험성이 큼
2-2. Cookie
- Cookie는 HttpOnly와 Seure 플래그를 설정하여 javascript 상에서 토큰에 접근할 수 없도록 막을 수 있어 비교적 안전함. 단 CSRF 취약점이 있어 이를 대비하기 위한 추가적인 조치들을 해주어야 함.
2-3. 서버에서 관리
- 서버에서 관리되면 브라우저 상에서 발생하는 보안 취약점을 해결할 수 있지만, 서버상의 보안 위험은 따로 관리 해주어야 함.
* XSS (Cross-site Scripting) : 유저의 브라우저에서 특정 스크립트를 실행시켜 원하는 정보를 탈취하는 방식
* CSRF (Cross-Site Request Forgery): 인증된 사용자로 하여금 서버에 접근해 의도치 않은 행동을 하게 하는 방식