서론
이 피드에서 공부하는것
JWT 란?
JWT 동작방식
연결
Reference :
jwt.io
https://www.jwt.io/introduction#what-is-json-web-token-structure
JSON Web Token Introduction - jwt.io
Learn about JSON Web Tokens, what are they, how they work, when and why you should use them.
www.jwt.io
Spring security : Oauth 2,0 Resource Server JWT
OAuth 2.0 Resource Server JWT :: Spring Security
Most Resource Server support is collected into spring-security-oauth2-resource-server. However, the support for decoding and verifying JWTs is in spring-security-oauth2-jose, meaning that both are necessary in order to have a working resource server that s
docs.spring.io
Inpa Dev님
🌐 JWT 토큰 인증 이란? (쿠키 vs 세션 vs 토큰)
Cookie / Session / Token 인증 방식 종류 보통 서버가 클라이언트 인증을 확인하는 방식은 대표적으로 쿠키, 세션, 토큰 3가지 방식이 있다. JWT를 배우기 앞서 우선 쿠키와 세션의 통신 방식을 복습해
inpa.tistory.com
JsonWebToken 이란?
Json 형태로 구성한 "사용자 정보를 담고있는" 토큰 이다.
여기서 토큰이란, 서버가 클라이언트를 인증하고 나면, "인증완료되었다" 라고 주는 일종의 징표이다.
JWT를 보기 전에, 인증이 되었음을 증명하는 수단이 뭐가있는데?
1. 쿠키
- 브라우저의 쿠키에 정보를 담아두고, Request가 날아올 때마다 브라우저가 함께 보내온 Cookie 데이터를 읽는 방식이다.

위 방식의 문제점이 뭘까?
지금처럼 cookie 목록을 손쉽게 조회할 수 있기때문에, 민감정보를 저장해두기에는 부적합하다.
또한 저 UI에서 수정도 직접 가능하다. 만약 저상태에서 수정하고 요청을 날리면 수정된 cookie 값이 request에 담겨 날아간다.
따라서 인증정보와 같은 민감한 정보를 담기에는 부적합하다
2. 세션
쿠키가 브라우저에 노출이 되서 부적합하다고? 그러면 브라우저는 이 정보를 모르게하면 되지않을까?
이 방법을 구현한게 "세션" 인증방식이다.
클라이언트의 민감정보, 인증정보 등등을 서버측에서 저장하고 관리하는 방법이 세션방식이다.
세션객체는 JSessionId를 Key로 가지고, [Value로 생성시각, 마지막 접근시각, Customized Key-value set]을 저장한 Map 을 value로 가진다.
이때, JSessionId 를 어떻게든 제시를 해야 "아까 나 로그인 했잖아!" 라고 주장할 수 있지 않겠는가?
이 부분도 Cookie에서 관리된다.일반적으로 서버가 발급한 JSessionId 를 cookie에 저장해두고,
Request가 날아갈 때 해당 Cookie가 읽히면서, Session 저장소(Memory||Redis||DB) 에서 해당 JSessionId 의 value를 가져와서 매핑한다.
JsessionId 역시 Cookie에서 관리하지만 민감정보 그 자체가 저장된것이 아니고,
Server가 해당 JsessionId의 value를 클라이언트로 리턴해서 값을 공개 하지 않는 이상 값을 알 수 없다.
이에 보안성이 조금은 향상되었다고 생각할 수 있겠다.
다만, 이 인증방식의 경우 다른 문제가 발생한다.
JsessionId 자체를 복사해다가 인증받지 않은 유저가 인증받은 유저인척 할 수 있다.
(물론 JSessionId에 IP까지 매핑하면 어느정도 보안이 향상되기는 하겠다)
다만, 요청이 많아지면 세션 저장소에서 데이터를 가져오는 작업이 빈번히 일어나, 오버헤드가 많이 발생하게되어, 부하가 가중되겠다.
여기서 이제 Token 방식이 나온것이다.
3. Token, 그중에서도 JWT
사실 Token 방식이라 한다면, 단순하게 서버에서 특정 값을 (api Key값) 넘겨주고, Client가 그걸 제시함으로써 서비스에 들어온다면,
그것도 토큰이라고 할 수 있지 않나? 라는 생각도 한번 해봤다.
다만, JWT와 다른점이라고 한다면 JWT는 그 토큰을 검증 및 조회함으로써 이미 인증에 요구되는 모든 정보를 수령할 수 있다는 차이점이 있겠다.
그리고 오히려 apiKey를 제시하고, 서버에서 저장소에서 해당 정보를 가져온다면 그건 세션방식에 가까운거겠지..
어쩃든!
JWT는 RFC 7519에 정의되어있으며, JSON 객체 형태로 정보를 안전하게 전송하는 방식이라 소개하고있다.
디지털 서명을 사용하기때문에 신뢰할 수 있으며, 암호화도 할 수 있다.
해당 페이지에서는 JWT를 어느경우에 사용해야 할까? 에 대해 아래와 같이 설명하고 있다.
A. Authorization(인증) :
일반적인 JWT 사용 시나리오이며, 한번 로그인 한 뒤에는 모든 Request가 JWT를 포함하고 전송되어야 하며,
이를 통해 사용자가 보호받고있는 자원에 접근할 수 있게한다.
특히 SSO는 JWT를 광범위하게 사용하는 기능이며, 오버헤드가 적고 이종 Domain간 정보를 제출하기 쉽기 때문이다.
B. 정보교환
JWT는 안전하게 정보를 교환하는 좋은 방법이다. JWT는 -예를들면, 공개키/비공개키 암호화- 디지털서명이 가능하기 때문에, 전송자 정보를 신뢰할 수 있다.
즉, 오버헤드가 적고 이종 도메인간 교환하기 쉬움을 큰 장점으로 밀고있는것같다.
물론 JWT도 탈취당하면 답이 없지만, Payload 자체에 로그인한 IP를 담고, Request IP를 검증하는 방식으로 보안을 늘릴 수 있다.
추가적으로 현업에서는 접근용 토큰과 갱신용 토큰을 발급해서, 접근용 토큰이 탈취당했을때의 회복전략을 구축해서 쓴다고 한다.
아쉽게도 나는 아직까진 세션을 사용해 개발한 경험밖에 없다.
따라서 기술을 경험해보고 차이점을 기억해두기 위해 이번 프로젝트에서는 JWT를 사용해보려 한다.
그렇다면, 이제 JWT가 어떻게 생겼는지 보자
JWT Structure
JWT는 "헤더.페이로드.시그니처" 로 구성되어있다. 실제로 String 값으로 ~~~~~.YRQA~~~.ZRQ~~ 이렇게 생겼다는 뜻이다.

JWT Header
JWT Header에는 일반적으로 2가지 정보가 담긴다. 서명 Algorithm 정보와, token type이 JWT임을 알리는 정보값이다.

이후, 이 header 정보를 BASE64 Url 인코딩을 수행해서 "헤더.페이로드.시그니처" 중 헤더값에 셋팅한다.
JWT Payload
"Claims", 즉 사용자 인증에 필요한 정보를 담고있는 파트다.
원문에서는 "Claims는 엔티티(일반적으로, 사용자) 와 부가적인 정보를 진술한 파트" 라고 하고있으며, Claims를 세분류로 나누어 설명한다.
A) Registered : 필수는 아니나 권장되는 기 선언된 집합이며, 상호 운용 가능한 클레임 집합이다. iss(발급자), exp(만료시간), sub(제목), aud(대상)이 있다.
B) public claims : 사용자가 자유롭게 구성할 수 있는 영역. 충돌 방지를 위해 URI 포맷을 이용해야 한다.
C) private : 사용자가 자유롭게 구성할 수 있는 영역. 서버와 클라이언트간 필요한 정보를 넣으며, 등록되지도, 공개되지도 않는다.

JWT Signature
서명부를 만들기 위해서는, 인코딩된 header, 인코딩된 payload, secret, header에 지정해둔 알고리즘을 가져와서 서명해야 한다고 한다. HMAC SHA256 알고리즘을 사용한다면, 아래와 같이 signature가 생성된다고.

JWT 사용을 위해서라면
A) 보호된 자원에 접근할 때, Bearer 스키마를 사용해 Authorization 헤더에 JWT를 포함시켜야 한다.

그래서, JWT가 뭔지는 알겠고 Spring에 어떻게 붙여야하는데?
Resource Server JWT in Spring security
Spring Security page에서는 Oauth2.0 Resource Server JWT로 소개하고있다.
또한 소개글 처음에, JWT 검증 및 디코딩은 spring-security-oauth2-jose 패키지에 있다고 한다.
이 글을 정리하기 전에 doc을 먼저 한번 훑어보니, JWT 자체 사용방법을 이야기 하는것이 아니라,
JWT를 이용하는 Oauth2.0 프로토콜에서의 자원서버 관점에서의 사용법을 이야기 하고있다.
OAuth 란, 내 자격증명을 다른 서버에 위임하고, 그 자격증명을 통해 받은 토큰으로 보호된 자원을 이용하는 방식을 의미한다.
즉, 사용자들이 내가 개발한 어플리케이션( resource 서버)를 이용할 때
사용자 ID, PW등을 나에게 맡기지 않고 Naver(Auth 서버) 와 같은 다른 사이트의 ID / PW를 통해 인증을 받고 토큰을 발급받아
그 토큰을 내가 개발한 어플리케이션(resource 서버)에 제시해서 통과하는 방식을 말한다.
Oauth2.0을 개발하긴 할거지만, 현 시점에서 보기에는 너무 앞질러 나간 감이 없잖아 있다.
또한 URL별로 나누면, 특정 URL로 들어올 때에는 Oauth 로그인, 또다른 특정 URL로 들어올 때는 일반 로그인등을 하게 할 수 있으니,
spring security documentation을 보고 구현하는건 나중으로 미뤄야겠다.
내가 생각하고 있는 "Self-contained JWT 인증" 방식은 공식문서에서 제공하고 있지 않기 떄문.
다만, JWT의 동작방식은 보고 넘어갈 만 한것 같다.
How JWT Authentication Works

1. authentication filter가 bearerToken을 읽어서 AuthenticationManager에게 전달
2. AuthenticationManager가 등록된 ProviderManager 중 JWT 타입을 support<>() 하는 ProviderManager를 Invoke
3. JWTAuthenticationProvider가 해당 값을 decode, verify, validate
4. JwtAuthenticationProvider가 Converter를 사용해, JWT를 granted Authorities 집합으로 변환
지금까지 공부한걸 토대로 아래와 같은 생각을 할 수 있다.
1. 로그인에 성공하면 Bearer로 시작하는 토큰을 제공하고 (Inpa님을 인용하여, Refresh용과 Access용 2개를 발급, Refresh용은 서버에서 보관)
2. 헤더의 Authorization 영역에 셋팅하게 하면 되고
3. Filter에서 해당 내용을 뽑아다가
4. AUthenticationProvider를 구현해서 거기서 검증하게 하면 되는데,
5. Access token이 만료되었다면 Refresh Token을 검증해서 새 Access Token를 던져주면 되곘구나!
정도로 정리할 수 있겠다.
이때 사용하는 패키지는 Spring security에서 언급한 패키지로 해볼 에정이다.

다만 이부분은 document에서 직접 언급을 하지 않으니, 최대한 이 Document를 읽어보고,
안되는건 그 부분만 chatGPT(심지어 돈내고 유료버전 쓰고있다) 를 활용해서 개발해보려고 한다.
오늘은 여기까지,
다음글은 개발일기 (Provider Customizing과 JWT 구현) 을 남겨보겠다.
'공부일기 : Spring' 카테고리의 다른 글
| Intellij static file hotswap, logback 설정 (0) | 2025.11.06 |
|---|---|
| Spring Security(2) : 로그인 절차 / security configure Customize하기전에 알아둘것 (0) | 2025.08.31 |
| Spring Security(1) : Spring Security 개념 (3) | 2025.08.17 |
| 책으로 Spring 개념 공부하기 : DI, IOC (1) (0) | 2023.04.11 |
| 책으로 Spring 개념 공부하기 : Spring Framework 란? (0) | 2023.04.11 |