JWT는 Json 포맷을 이용하여 사용자에 대한 속성을 저장하는 클레임 기반의 웹 토큰이다. 클라이언트와 서버 간의 상태를 저장하는 데 유용하며 주로 인증과 권한 부여를 위해 사용된다.
JWT의 구성으로는 헤더와 페이로드, 서명이 포함되어 있으며, 헤더는 토큰의 타입과 서명 알고리즘을 지정하고, 페이로드는 사용자 정보와 같은 클레임을 포함한다. 서명은 헤더와 페이로드를 조합하여 비밀키를 사용해 이 서명은 토큰이 변조되지 않았음을 보장한다.

보통 사용자가 로그인을 하면 서버는 JWT를 생성해서 반환하고, 클라이언트는 이 JWT를 로컬 스토리지나 쿠키에 저장한 뒤 서버에 요청할 때 JWT를 포함하여 인증한다. 그리고 서버는 요청에 포함된 JWT를 검증해서 사용자의 인증과 권한을 확인한다.
JWT의 장점으로는 서버가 상태를 저장할 필요가 없어서 서버간의 세션 공유가 필요없고, 따라서 확장성이 좋다. 그리고 토큰에 사용자 정보와 권한이 포함되어 있어서 서버가 별도로 정보를 조회할 필요가 없다.
하지만, 그만큼 보안에 주의가 필요하고, 정보가 많아질수록 토큰의 길이가 늘어나서 네트워크에 부하를 줄 수 있다. (토큰 만료 시간 필수)
🌟 추가 질문
📍 AccessToken과 RefreshToken은 무엇인가?
액세스 토큰은 자원에 바로 접근할 수 있도록 확인해주는 토큰이고, 리프레시 토큰은 액세스 토큰이 만료되었을 때 토큰을 재발급 받기 위해 사용하는 토큰이다.
📍 AccessToken의 만료되는 시점은 언제로 가져가는 것이 좋을까?
엑세스 토큰은 탈취 당했을 때 얼마나 공격을 받아도 될까 라는 의미가 될 수도 있다. 그래서 짧게 가지면 가질수록 탈취 당했을 때 공격받는 시간이 줄어든다.
그렇다면 리프레시 토큰은 어떨까? 리프레시 토큰은 일반적으로 엑세스 토큰보다 길게 가져간다. 하지만 똑같이 탈취를 당하면 액세스 토큰을 발급받아 사용할 수 있기 때문에 위험하다.
보통 헤더에 엑세스 토큰과 리프레시 토큰을 넣어 요청을 보내는데, 조금 더 보안적으로 신경을 쓴다면, 리프레시 토큰을 쿠키에 담아 보내는 경우도 있다. 그 이유는 스크립트를 사용해서 헤더에는 접근이 가능하지만, 쿠키에는 접근이 불가능하기 때문이다.
또한, 탈취 당했을 경우를 대비해 이 토큰을 한번 더 체크할 수 있는 장치가 있으면 좋다.
예를 들어 분산 캐시나 레디스에 엑세스 토큰과 리프레시 토큰 등을 페어로 저장을 해두고, 사용자가 API 요청을 보낼 때마다 해당 토큰을 이 저장된 정보와 비교하여 유효성을 검증한다. 그리고 보안적으로 이슈가 생겼을 때, 서버는 해당 토큰이 저장된 분산 캐시의 데이터를 삭제하거나 무효화하고 사용자는 재로그인을 시도해야만 새로운 토큰을 발급받을 수 있도록 유도할 수 있다.
참고 자료
[Server] JWT(Json Web Token)란?
Access Token & Refresh Token