JWT(Json Web Token) 기초
JWT
JWT(Json Web Token)란 인증에 필요한 정보들을 암호화 시킨 토큰을 의미한다. JWT 기반 인증은 쿠키/세션 방식과 유사하게 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별한다.
구조
JWT는 .을 구분자로 나누어지는 세 가지 문자열의 조합으로, 실제 해당 JWT 문자열들을 디코딩 하면 다음과 같은 구조를 가진다.
1. header
암호화 해싱 알고리즘 정보와 토큰의 타입. JWT를 어떻게 검증(Verify)하는가에 대한 내용을 담고 있다.
2. Payload
JWT의 내용이다. 페이로드(Payload)에 있는 속성들을 클레임 셋(Claim Set)이라 부른다. 클레임 셋은 JWT에 대한 내용(토큰 생성자(클라이언트)의 정보, 생성 일시 등)이나 클라이언트와 서버 간 주고 받기로 한 값들로 구성된다.
(토큰에 담을 정보로, 클라이언트의 고유 ID 값과 유효 기간 등이 포함)
3. Signature
점(.)을 구분자로 해서 헤더와 페이로드를 합친 문자열을 서명한 값이다. 서명은 헤더의 alg에 정의된 알고리즘과 비밀 키를 이용해 성성하고 Base64 URL-Safe로 인코딩한다.
(인코딩된 header와 payload를 합쳐 비밀키로 해싱. 토큰에 담긴 header와 payload는 쉽게 복호화가 가능하지만 Signature는 서버측에서 관리하는 비밀키가 유출되지 않는 이상 복호화 할 수 없음)
Access Token / Refresh Token
access token 은 refresh token 모두 사용자가 로그인을 하고 인증됐을 경우 서버에서 비밀키를 사용해서 발급한다.
- access token 은 글자 그대로 사용자가 서버에 요청(request)를 보낼 때 header에 함께 보내는 접근용 토큰으로 만료 시간을 10분정도로 짧게 두어 자주 발급받게 한다. 따라서 access. token을 탈취 당하더라도 금방 만료되어 안정성이 유지된다.
- refresh token 은 access token이 만료됐을 때 access token을 재발급받기 위한 인증용 토큰이다. 평소의 요청에는 request에 포함되지 않으면 오직 access token을 재발급받는 용도로만 사용한다. 만료 기간은 자동 로그인 기능을 몇 달로 지정할 것인 가에 따라 조절하면 되고, 만료 기간이 끝나면 사용자에게 로그인을 다시 요청하면 된다. (대부분 refresh token을 DB에 저장해서 관리한다.)
인증 과정
1. 클라이언트의 로그인 요청이 들어오면 서버는 검증(ID / PW과 유효하다면) 후 클라이언트 고유 ID 등의 정보를 Payload에 담는다.
2. 암호화할 비밀키를 사용해 JWT(Access Token / Refresh Token)을 발급한다.
3. 클라이언트는 전달받은 토큰을 저장해두고, 서버에 요청할 때 마다 토큰을 요청 헤더 Authorization 에 포함시켜 함께 전달한다. (access token 을 header에 넣어서 전달)
4. 서버는 토큰의 Signature를 비밀키로 복호화 한 다음, 위변조 여부 및 유효기간 등을 확인한다.
- 만약 여기서 access token이 만료 되었다면 서버는 401 에러와 같은 권한 없음을 응답한다.
- 사용자는 다시 access token + refresh token을 header에 실어서 함께 요청한다.
- 사용자가 보낸 refresh token 과 DB에 저장해놓은 refresh token을 비교 및 검증한다.
- 검증에 성공했다면 새로운 access token을 발급한다.
5. 유효한 토큰이라면 요청에 대한 응답을 전달한다.
(실제 환경에서는 프론트 단에서 access Token의 payload 정보를 통해 만료 시간을 미리 확인한다. 따라서 데이터 요청 전에 access token을 미리 재발급 받아놓는다.)
장점
- 세션/쿠키 기반의 로그인 환경 구현시 Redis와 같은 세션 스토리지를 따로 관리해야 하지만 JWT의 경우 클라이언트의 로컬 스토리지에 저장하기 때문에 별도의 저장소를 관리하지 않아도 된다.
- 세션 정합성 불일치 문제처럼 scale out 환경에서 발생하는 문제점을 사전에 차단할 수 있기 때문에 서버 확장성이 매우 뛰어나다.
단점
- 세션/쿠키의 경우 해킹이나 탈취로 인해 문제가 발생했을 때 해당 세션을 제거하여 강제로 로그아웃 시켜버릴 수 있지만 JWT의 경우 한번 발급되면 강제로 삭제하는 방법이 없다.
-> 해당 단점을 보완하기 위해 access Token의 유효기간을 짧게 (10분~15분) 설정하고 refresh Token을 관리하는 방식을 사용한다. - JWT의 긴 길이로 인해 인증이 필요한 요청이 많을 수록 서버의 자원을 많이 사용할수 밖에 없다.
출처 : https://1-7171771.tistory.com/159?category=972766