쿠키란 클라이언트가 웹사이트에 접속할 때, 그 사이트에서 사용한 일련의 작은 기록 파일이다.
서버가 클라이언트에 정보를 전달할 때 저장하고자 하는 응답 헤더(Cookie)에 저장하여 전달하고 Key-Value 형식의 문자열 형태로 저장한다.
무언가에 대한 특정 인증 정보(세션 ID)를 서버가 가지고 있고, 그 값을 클라이언트에게 전달하여 마치 키를 주고 자물쇠를 여는 방식으로 인증한다.
쿠키의 값이 그대로 노출되는 보안 문제점을 보완하기 위해 나온 것이 세션이다.
만약 세션이 탈취 되는 등, 보안의 문제가 발생한다 하더라도 서버에 저장되어 있는 세션을 모두 지워버리고 새로 발급하게 하면 된다.
JWT는 인증에 필요한 정보들을 Token에 담아 암호화시켜 사용하는 하나의 인터넷 표준 인증 방식이다. 서버의 별도 저장없이 인증절차를 진행하기 때문에 세션의 단점을 해결할 수 있다.
JWT의 각각의 구성 요소(Header, Payload, Signature)가 점(.)으로 구분되어 있다.


Header에는 보통 토큰의 타입이나 서명 생성에 어떤 알고리즘이 사용되었는지 저장한다.

Payload에는 보통 Claim이라는 사용자나 토큰에 대한 정보를 Key-Value의 형태로 저장한다.
JWT 표준 스펙
1. iss(Issuer): 토큰 발급자
2. sub(Subject): 토큰 제목 - 토큰에서 사용자에 대한 식별값이 된다.
3. aud(Audience): 토큰 대상자
4. exp(Expiration Time): 토큰 만료 시간
5. nbf(Not Before): 토큰 활성 날짜(해당 날짜 이전의 토큰은 활성화되지 않음을 보장)
6. iat(Issued At): 토큰 발급 시간
7. jti(JWT id): JWT 토큰 식별자 (issure가 여러 명일 때 이를 구분하기 위한 값)
이러한 표준 스펙이 있다는 것이지 위 7가지를 모두 포함해야 하는 것은 절대아니다. 서버 상황에 따라 가져야 할 인증 체계에 따라 사용하면 된다.
표준 스펙 이외에도 필요하다면 아래와 같이 추가하고 싶은 목록을 추가해도 된다.

다만 payload는 암호화가 되있지 않고 Base64 인코딩되있다. 그래서 누구나 디코딩을 하면 내용을 볼 수 있기 때문에 민감정보를 담지 말아야 한다.
그래서 JWT에는 단순히 식별을 하기 위한 정보만을 담아야 한다.

JWT의 예외들은 모두 RuntimeException과 JwtException의 하위 클래스이다.
ClaimJwtException: JWT의 claim 유효성 검증이 실패했을 경우
ExpiredJwtException: 만료된 JWT 수신한 경우
MalformedJwtException: JWT의 구조가 올바르지 않은 경우
PrematureJwtException: 접근이 허용되기 전에 JWT가 수신된 경우
SignatureException: 시그너처 연산이 실패하였거나, JWT의 시그너처 검증이 실패한 경우
UnsupportedJwtException: 애플리케이션에서 예상하는 형식과 일치하지 않는 특정 형식/구성으로 JWT를 수신한 경우, 예를 들어 애플리케이션에 암호화로 서명된 클레임 JWS가 필요한 경우 서명되지 않은 일반 텍스트 JWT를 구문 분석하는 경우 이 예외가 발생합니다
https://javadoc.io/doc/io.jsonwebtoken/jjwt-api/0.11.2/index.html