joooii

[64일차] JWT 본문

TIL

[64일차] JWT

joooii 2025. 12. 2. 18:39

 

 

웹 시큐리티(Web Security)를 학습하면서 웹 보안에서 사용하는 인증 방식인 JWT에 대해 알아보고자 한다.

 

JWT란?

JWT(Json Web Token)는 인증에 필요한 정보들을 암호화시킨 JSON 포맷을 이용하여 유저를 인증하고 식별하기 위한 토큰(Token) 기반의 인증 방식이다. 이때 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별한다.

 

JWT는 JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것이며, 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자서명도 포함되어 있다.

 

 

JWT 구조

JWT는 `.`을 구분자로 나누어지는 세 가지 문자열의 조합이다.

`.`을 기준으로 좌측부터 Header, Payload, Signature를 의미한다.

출처: https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-JWTjson-web-token-%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC#jwt_json_web_token_%EC%9D%B4%EB%9E%80

 

1. Header

Header에는 JWT에서 사용할 타입과 해시 알고리즘의 종류가 담겨있다.

 

2. Payload

Payload에는 서버에서 첨부한 사용자 권한 정보와 데이터가 담겨있다. 

 

3. Signature

Signature에는 Header, Payload를 Base64 URL-safe Encode를 한 이후 Header에 명시된 해시함수를 적용하고, 개인키(Private Key)로 서명한 전자서명이 담겨있다.

 

HeaderPayload는 단순히 인코딩 된 값이기 때문에 제 3자가 복호화 및 조작이 가능하지만, Signature는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화가 불가능하다. 그렇기에 Signature는 토큰의 위변조 여부를 확인하는 데 사용되며 이는 제 3자에게 알려지면 안 된다.

 

아래 JWT 공식사이트에서 쉽게 JWT 토큰을 인코딩(생성)하거나 디코딩할 수 있다. 

 

 

JSON Web Tokens - jwt.io

JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).

www.jwt.io

 

 

Access Token과 Refresh Token

앞서 설명한 것과 같이 JWT 토큰을 사용해서 클라이언트와 서버는 안전하게 통신할 수 있다. 이때 제 3자가 JWT 토큰을 탈취하여 로그인하게 된다면, 실제 로그인한 유저와 제 3자 중 누가 로그인한 지 확인할 수 없기 때문에 서버는 있는 그대로 유저의 정보를 제공할 수 밖에 없다.

따라서 토큰의 유효 기간을 두어서 유효 기간이 지나면 토큰을 재발급하여 이러한 보안 문제를 해결할 수 있다.

 

이때 필요한 개념이 `Access Token`과 `Refresh Token`이다.

일반적으로 Access Token은 첫 로그인 시 발급받는 토큰으로 유효 기간을 짧게 설정하며, Refresh Token은 Access Token이 만료되어 갱신될 때만 사용하기 때문에 유효 기간을 길게 설정한다.

 

유효 기간을 이렇게 가져가는 이유는 Access Token은 매 요청마다 서버로 전송되므로 탈취될 가능성이 더 높다. 그렇기에 유효 기간을 짧게 하여 위험 노출 기간을 최소화한다.

Refresh Token은 오직 "토큰 재발급" 요청에만 사용되므로 노출 빈도가 낮다. 그렇기에 상대적으로 긴 유효 기간을 부여할 수 있다.

출처: https://stormstudy.tistory.com/62

 

JWT 프로세스

JWT 프로세스

  1. 사용자가 로그인 요청을 보낸다.
    - ID와 비밀번호를 전송하여 서버에 인증을 요청한다.
  2. 서버가 인증에 성공하면 Access Token과 Refresh Token을 발급한다.
    - Access Token은 짧은 만료 시간을 가지며, Refresh Token은 상대적으로 긴 만료 시간을 가진다.
    - Access Token은 클라이언트 메모리나 상태관리(Store)에 저장되고, Refresh Token은 HttpOnly 쿠키 또는 보안 저장소에 보관된다.

  3. 클라이언트는 Access Token을 이용해 API 요청을 보낸다.
    - 일반적으로 Authorization 헤더에 Bearer 토큰 형태로 포함한다.

  4. 서버는 Access Token을 검증한 뒤 문제가 없으면 요청에 대한 정상 응답을 반환한다.
    - 검증 과정에는 서명 확인, 만료 여부 체크, 변조 여부 검사 등이 포함된다.

  5. Access Token이 만료되면 클라이언트는 Refresh Token을 사용해 새로운 Access Token 발급을 요청한다.
    - 예: `POST /auth/refresh`

  6. 서버는 Refresh Token을 검증한 뒤 유효하다면 새로운 Access Token을 발급해 반환한다.
    - Refresh Token이 만료되었거나 변조되었다면 재로그인이 필요하다.

 


Spring에서 JWT 구현 (일부 코드만 발췌)

1. 라이브러리 추가 (maven)

// pom.xml

<!-- JWT -->
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
	<groupId>io.jsonwebtoken</groupId>
	<artifactId>jjwt-api</artifactId>
	<version>0.12.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency>
	<groupId>io.jsonwebtoken</groupId>
	<artifactId>jjwt-impl</artifactId>
	<version>0.12.6</version>
	<scope>runtime</scope>
</dependency>

 

 

2. JWT 발급

    2.1. User Service를 통해 인증을 확인한다.

    2.2. 인증된 경우 JWT 토큰을 발급한다.

    2.3. 토큰 정보를 응답한다.

 

 

3. 전달 받은 토큰의 유효성 검사

    - interceptor에서 유효성 검사

 

 

4. JWT 토큰에서 필요한 정보 추출

 

 

5. Access Token이 만료된 경우, Refresh Token으로 재발급

 

 


회고

이번 주차에는 JWT 기반 인증 방식을 중심으로 웹 시큐리티 개념을 학습했다.


JWT가 단순히 “토큰을 발급하는 방식”이 아니라, Header·Payload·Signature 구조를 통해 위변조를 방지하고, Access Token과 Refresh Token을 분리해 보안성을 강화하는 체계적인 방식이라는 점을 이해할 수 있었다.

 

또한 JWT는 토큰 탈취(XSS 등)나 강제 폐기가 어렵다는 단점도 있기 때문에, 실제 서비스에서는 적절한 저장 방식과 추가적인 보안 정책이 반드시 필요하다는 점을 배울 수 있었다.

 

미니 프로젝트 때 백엔드 파트를 구현하면서 JWT로 Access Token 발급까지는 시도했으나, Refresh Token으로 Access Token 재발급하는 과정에서 막혀서 구현하지 못했다.

이번에 미니 프로젝트 프론트엔드 파트를 구현하면서 로그인 관련 부분도 추가적으로 구현해서 보안을 강화해야겠다는 생각이 들었다.

 

 

 

아 그리고 TIL 챌린지 우수참여자 목록에 들었다! 기대도 안 하고 있었는데 우수참여자로 뽑아주니 너무 감사했다!!

그리고 무엇보다 내가 쓴 TIL에 대한 소감평까지 작성해 주셔서 더욱 뿌듯하고 앞으로 더 잘 쓰고 싶다는 생각이 들었다.

앞으로도 열심히 작성해야징

'TIL' 카테고리의 다른 글

[74일차] Spring Boot에서 이미지 파일 관리하기  (0) 2025.12.16
[65일차] 웹 시큐리티  (0) 2025.12.08
[58일차] Zustand  (0) 2025.11.24
[53일차] TypeScript와 Vite  (1) 2025.11.17
[49일차] React Hooks  (0) 2025.11.10