JWT(JSON Web Token)란?
JWT란 JSON 포맷을 이용해 사용자에 대한 속성을 저장하는 Claim 기반의 웹 토큰이다. 토큰 자체를 정보로 사용하는 Self-Contained 방식으로 정보를 안전하게 전달한다.
JWT의 구조
JWT는 헤더, 내용, 서명 순서대로 세 파트로 구성된다.
1. 헤더(Header)
- 헤더는 토큰의 타입, 해싱 알고리즘으로 구성된다.
- 토큰의 타입 : JWT
- 해싱 알고리즘 : HMAC SHA256 혹은 RSA (토큰을 검증할 때 Signature 부분에서 사용된다.)
{
"typ": "JWT",
"alg": "HS256"
}
2. 내용(Payload)
- 토큰에 사용자가 담고자 하는 정보를 담는 곳
- 토큰에서 사용할 정보의 조각들인 Claim이 담긴다.
- 토큰에는 여러 개의 Claim이 담길 수 있다.
Claim
- Payload에 담기는 정보의 한 조각을 Claim 이라고 한다.
- JSON 형태의 Key, Value 형태로 한 쌍으로 이루어져 있다.
Claim의 종류
- 등록된 클레임(Registered Claim)
- 토큰 정보를 표현하기 위해 이름이 이미 정해진 종류의 데이터
- 등록된 클레임의 사용은 모두 선택적이지만 사용하는 것이 권장됨
- iss: 토큰 발급자 (issuer)
- sub: 토큰 제목 (subject), 주로 유니크한 사용자 이메일
- aud: 토큰 대상자 (audience)
- exp: 토큰의 만료시간 (expiraton), NumericDate 형식이고 언제나 현재 시간보다 이후로 설정되어있어야 한다.
- nbf: Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념, NumericDate 형식이고, 이 날짜가 지나기 전까지는 토큰이 처리되지 않는다.
- iat: 토큰이 발급된 시간 (issued at), 토큰의 age 가 얼마나 되었는지 판단 할 수 있다.
- jti: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용된다. 일회용 토큰에 사용하면 유용
- 공개 클레임(Public Claim)
- 사용자 정의 클레임으로, 공개용 정보를 위해 사용한다.
- 충돌이 방지된 이름을 갖고 있어야 한다.
- 충돌 방지를 위해 클레임 이름을 URI 형식으로 짓는다.
- 비공개 클레임(Private Claim)
- 사용자 정의 클레임으로, 클라이언트와 서버가 협의하에 임의로 지정한 정보를 저장해서 사용
- 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할 때 유의해야 한다.
3. 서명(Signature)
- 서명은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다.
- 헤더(Header)와 내용(Payload)의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀키를 이용해 헤더에서 정의한 알고리즘으로 해싱을 하고, 이 값을 다시 BASE64로 인코딩하여 생성한다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
장단점
장점
- 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 별도의 인증 저장소가 필요 없다.
- Secret key만 공유된다면 각 서버에서 토큰 유효성 검증이 가능하다.
- 쿠키를 전달하지 않아도 되므로 쿠키를 사용함으로써 발생하는 취약점이 사라진다.
- URL 파라미터와 헤더로 사용
- 수평 스케일이 용이함
- 트래픽 대한 부담이 낮음
- REST 서비스로 제공 가능
- 내장된 만료
- 독립적인 JWT
단점
- Self-contained: 토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있다.
- 토큰 길이: 토큰의 페이로드(Payload)에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다.
- Payload 인코딩: 페이로드(Payload) 자체는 암호화 된 것이 아니라, BASE64로 인코딩 된 것이다. 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 Payload에 중요 데이터를 넣지 않아야 한다.
- Stateless: JWT는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능하다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어야 한다.
- Tore Token: 토큰은 클라이언트 측에서 관리해야 하기 때문에, 토큰을 저장해야 한다.
참고자료
728x90
'# Back-End > Spring' 카테고리의 다른 글
@Secured, @PreAuthorized를 이용한 메소드 수준의 권한 적용 (0) | 2022.01.23 |
---|---|
Role Enum 클래스를 이용한 인가 (0) | 2022.01.23 |
Spring Security란? (0) | 2022.01.23 |
인증 방식 비교(서버 기반 인증, 토큰 기반 인증) (0) | 2022.01.23 |
Filter, Interceptor, AOP (필터, 인터셉터, AOP) (0) | 2022.01.23 |
[Test] Spring Layer별 테스트 작성 (1) | 2022.01.23 |
[Test] Spring Boot 테스트 클래스 정의 어노테이션 (0) | 2022.01.23 |