JSON 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token 즉, 토큰의 한 종류
일반적으로 쿠키 저장소를 사용하여 JWT를 저장


Session 마다 다른 Client 로그인 정보를 가지고 있을 수 있음
만약 Client 1의 로그인 정보를 가지고 있지 않은 Sever2 나 Server3 에 API 요청을 하게되면 문제가 발생?
해결방법
1) Sticky Session: Client 마다 요청 Server 고정
2) 세션 저장소 생성하여 모든 세션을 저장


모든 서버에서 동일한 Secret Key 소유
Secret Key 통한 암호화 / 위조 검증 (복호화 시)

동시 접속자가 많을 때 서버 측 부하 낮춤
Client, Sever 가 다른 도메인을 사용할 때
구현의 복잡도 증가
JWT 에 담는 내용이 커질 수록 네트워크 비용 증가 (클라이언트 → 서버)
기 생성된 JWT 를 일부만 만료시킬 방법이 없음
Secret key 유출(외부로) 시 JWT 조작 가능
서버에서 " 로그인 정보 " --> JWT로 암호화(Secret Key 사용)

서버에서 직접 쿠키를 생성해 JWT를 담아 Client 응답에 전달
JWT 전달 방법은 개발자가 정함
Cookie cookie = new Cookie(AUTHORIZATION_HEADER, token); // Name-Value
cookie.setPath("/");
// Response 객체에 Cookie 추가
res.addCookie(cookie);

1) 서버에서 API 요청 시마다 쿠키에 포함된 JWT를 찾아서 사용
// HttpServletRequest 에서 Cookie Value : JWT 가져오기
public String getTokenFromRequest(HttpServletRequest req) {
    Cookie[] cookies = req.getCookies();
    if(cookies != null) {
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(AUTHORIZATION_HEADER)) {
                try {
                    return URLDecoder.decode(cookie.getValue(), "UTF-8"); // Encode 되어 넘어간 Value 다시 Decode
                } catch (UnsupportedEncodingException e) {
                    return null;
                }
            }
        }
    }
    return null;
}
2) Server
Client가 전달한 JWT 위조 여부 검증(Secret Key 사용)
JWT 유효 기간이 지나지 않았는지 검증
JWT는 누구나 평문으로 복호화 가능
Secret Key가 없으면 JWT 수정 불가능
--> Read Only 데이터
HEADER
{
  "alg": "HS256",
  "typ": "JWT"
}
{
  "sub": "1234567890",
  "username": "카즈하",
  "admin": true
}
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)