[스프링 시큐리티] JWT(Json Web Token)이란?
JWT(Json Web Token)이란?
JWT는 인증에 필요한 정보들을 Base64로 인코딩 시킨 JSON 토큰을 의미합니다.
즉, JWT 유저를 인증하고 식별하기 위한 토큰 기반 인증입니다.
또한, JWT를 이용한 방식은 다음과 같은 특징이 있습니다.
1.토큰 자체에 사용자의 정보들이 포함되어 있는 Self-containded한 특징이 있습니다.
2.RESTful과 같은 무상태(stateless)인 환경에서 사용자 데이터를 주고받을 수 있습니다.
3.세션(Session)을 사용하게 되면 사용자를 식별하기 위한 정보를 서버에 세션에 저장했지만,
토큰을 클라이언트에 저장하고 요청 시 HTTP 헤더에 JWT을 첨부하여 인증을 진행하고 데이터를 요청하고 응답을 받을 수 있습니다.
JWT(Json Web Token)의 구조
JWT는 각 요소가 .(점)으로 구분되고 구성 요소는 heaer,payload 그리고 signature입니다.
1.Header(헤더)
header에는 토큰의 타입과 전자 서명 시 어떤 종류의 알고리즘이 사용되었는지 명시합니다.
{
"alg": "HS256",
"typ": "JWT"
}
2.payload(페이로드)
payload에는 토큰에서 사용할 정보의 조각들인 claim이 담겨있습니다.
Json(key-value) 형태로 이루어진 쌍들이이 모두 하나의 claim입니다.
JWT의 표준 스펙에서는 7가지의 claim이 있으며 7가지를 전부 포함해야 되는 것도 아니고, 필요에 따라 claim을 추가해서 사용하면 됩니다.
iss: 토큰 발급자(issuer)
sub: 토큰 제목(subject)
aud: 토큰 대상자(audience)
exp: 토큰 만료 시간
nbf: 토큰 활성 날짜
iat: 토큰 발급 시간
jti: JWT 토큰 식별자(JWT ID), 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용
{
"sub": "1234567890",
"lat": 1516239022,
"exp" : 1669411871,
"email" : 1fdfa@naver.con
}
3.signature(서명)
서명(signature)은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드입니다.
JWT signature은 암호화되어 있어 외부에서 디코딩을 하더라도 실제 서명부가 나타나지 않고 암호화 구조만 나타납니다.
JWT는 헤더와 페이로드를 base64UrlEncode를 사용하여 인코딩을 합니다.
그리고 헤더에 지정된 알고리즘을 가져와 아래와 같은 형식(예제는 HMAC)으로 만듭니다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
JWT 구조를 통해 이해하는 JWT 인증 과정 (출처 : https://ksh-coding.tistory.com/58)
1. JWT 토큰을 클라이언트가 서버에 요청 시 Http Header에 담아 요청합니다.
2. 서버에서 Http Header의 JWT 토큰을 꺼내서 가져옵니다.
3. 클라이언트가 요청한 JWT 토큰을 서버가 가지고 있는 개인키를 가지고 Signature를 복호화합니다.
4. 복호화한 Signature의 base64UrlEncode(header)/base64UrlEncode(payload)가
각각 요청한 JWT 토큰의 header, payload와 일치하는지 검증합니다.
5. 일치한다면 인증을 허용하고, 일치하지 않는다면 인증이 실패합니다.
JWT - Access Token과 Refresh Token이란?
access token과 refresh token 두 가지는 JWT의 종류입니다.
Access Token이란?
Access token이란 보호된 정보들에 접근할 수 있는 권한 부여에 사용됩니다.
즉, 사용자를 인증하고 자원에 대한 접근을 위한 토큰입니다.
예를 들어 ,
1.로그인 성공 JWT 발급 : 서버측 -> 클라이언트로 JWT 발급
2.권한이 필요한 모든 요청 : 클라이언트 -> 서버측 JWT 전송
엑세스 토큰을 검증하여 권한을 가지고 있는 올바른 요청이라면 응답을 보내줍니다.
이때, 해커는 XSS를 이용하거나 HTTP 통신을 가로채서 이 토큰을 훔칠 수 있기 때문에 이러한 문제를 방지하기 위한 개념으로
Refresh Token 개념이 등장했습니다.
Refresh Token이란?
access token이 만료될 때 마다 refersh token을 통해 access token을 재발급해주기 위한 토큰입니다.
결과적으로 access token은 로그인 등 정보에 접근할 수 있는 카드키이고 refersh token은 카드키 재발급이라고 생각하면 이해하기 쉽습니다.
Access Token과 Refresh Token의 생명 주기
그렇다면, 해커의 공격을 방지하기 위해 Access Token과 Refresh Token가 어떻게 사용되는것일까요?
아래와 같은 로직으로 Access Token과 Refresh Token를 이용하여 해커의 공격을 방지할 수 있습니다.
1.로그인 성공 시 생명 주기와 활용도가 다른 토큰 2개 발급 : Access / Refresh
Access token : 권한이 필요한 모든 요청 헤더에 사용될 JWT로 탈취 위험을 낮추기 위해 생명 주기를 짧게 설정합니다.
Refresh token : Access Token이 만료되었을 때 재발급 받기 위한 용도로만 사용되며 생명 주기를 길게 설정합니다.
2.권한이 필요한 모든 요청은 Access token을 통해 요청
Access token만 사용하여 권한이 필요한 요청합니다.
3.권한이 알맞다는 가정하에 2가지 상황 : 데이터 응답, 토큰 만료 응답
4.토큰이 만료된 경우 Refresh 토큰으로 Access 토큰을 발급
Access 토큰이 만료되었다는 요청이 들어왔을 경우 서버측에서는 refresh 토큰을 검증 후 Access 토큰을 새로 발급합니다.
access token - refresh token 차이점 (출처 : https://ksh-coding.tistory.com/58)
1. AccessToken
처음 로그인 요청 시 서버에서 실제 유저의 정보가 담긴 AccessToken을 발행합니다.
클라이언트는 이 AccessToken을 저장한 후, 요청마다 AccessToken을 보내서
해당 AccessToken을 서버에서 검증 후 유효하면 요청에 맞는 응답을 진행합니다.
2. RefreshToken
처음 로그인 요청 시 서버에서 AccessToken 재발급 용도인 RefreshToken을 발행합니다.
이때, 클라이언트는 RefreshToken을 저장하지 않고 RefreshToken은 보통 서버 DB에 저장됩니다.
RefreshToken이 유효하면, AccessToken의 재발급을 진행합니다.
즉, Access token은 인증 처리역할 / Refresh token은 access token의 재발급 역할을 수행합니다.
개인 공부를 위해 작성된 글입니다. 잘못된 부분은 지적해주시면 수정하겠습니다.
출처:
https://blog.bizspring.co.kr/테크/jwt-json-web-token-구조-사용/
https://ksh-coding.tistory.com/58
https://mangkyu.tistory.com/56