G-PBL

JWT

연 동 2025. 4. 3. 09:17

요즘은 Bestia의 프론트엔드 개발자로서 다양한 기능들을 개발중입니다.

유저 기능을 개발하던 중, 유저 인증 및 보안과 관련된 이슈를 챙기기 위한 인증 방식으로 JWT를 선택하였고, 이를 클라이언트-백엔드 간 전달하는 방식을 header와 httpOnly 쿠키로 결정하였습니다.

 

# 목차

1. JWT란?

2. JWT를 어떻게 사용하나요?

3. 실제 사용 예시

 

# JWT란?

JSON Web Token의 줄임말입니다.

서버와 클라이언트 사이에서 인증 정보를 주고받을 때 사용하는 토큰 기반 인증 방식입니다.

 

여기서 토큰이란,

증명서 역할을 하는 문자열인데요,

어떤 사용자가 누구인지, 어떤 권한이 있는지를 담고, 서버가 신뢰할 수 있게 서명해둔 형태입니다.

JWT는 이 토큰을 JSON 형식으로 구성하고, Base64로 인코딩한 문자열입니다.

 

JWT의 구조를 살펴보자면,

Header 어떤 알고리즘으로 서명했는지 (예: HS256, RS256 등)
Payload 실제 데이터, 즉 유저 정보 (email, userId, role 등)
Signature Header와 Payload를 비밀 키로 사용해 서명한 값 (위조 방지용)

이렇게 3가지 파트로 이뤄져있는데, "."으로 구분합니다.

실제 예시와 함께 살펴봅시다.

 

아래는 GPT를 통해 생성한 Access Token입니다.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NSIsInVzZXJuYW1lIjoiam9obmRvZSIsImVtYWlsIjoiam9obkBleGFtcGxlLmNvbSIsImlhdCI6MTcwODAwMDAwMCwiZXhwIjoxNzA4MDAzNjAwfQ.5mVUeqqS9w2VOfMqtXkcvYeACrAh_XcIAG8QqEDUP3I

 

이를 "."을 기준으로 쪼개보면,

 

1. Header:     eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9  
2. Payload:    eyJ1c2VySWQiOiIxMjM0NSIsInVzZXJuYW1lIjoiam9obmRvZSIsImVtYWlsIjoiam9obkBleGFtcGxlLmNvbSIsImlhdCI6MTcwODAwMDAwMCwiZXhwIjoxNzA4MDAzNjAwfQ  
3. Signature:  5mVUeqqS9w2VOfMqtXkcvYeACrAh_XcIAG8QqEDUP3I

아래와 같은 결과가 나옵니다.

 

위 내용을 Base64를 통해 다시 디코딩하면,

 

1. Header

Header에는 어떤 서명 알고리즘을 사용해서 Signature를 만들었는지와 토큰이 어떤 타입인지에 대해 나타납니다.

{
  "alg": "HS256",  // HMAC-SHA256 알고리즘 사용
  "typ": "JWT"	   // JWT 사용
}

 

 

2. Payload

여긴 유저의 정보가 나타납니다.

{
  "userId": "12345",		// 사용자 고유 ID
  "username": "johndoe",	// 사용자 이름
  "email": "john@example.com",	// 사용자 이메일
  "iat": 1708000000,		// 발급 시간 (Issued At) → UTC 기준 초 단위 (epoch time)
  "exp": 1708003600		// 만료 시간 (Expires At) → 1시간 뒤
}

 

 

3. Signature

Header와 Payload를 비밀 키로 HMAC-SHA256 방식으로 서명한 값입니다.

서버는 이 서명을 확인해 위조 방지를 수행합니다.

토큰이 위조되지 않았는지 검증하고, 서명이 다르다면 Header나 Payload가 위조되었다 판단하고 인증을 거부합니다.

 

5mVUeqqS9w2VOfMqtXkcvYeACrAh_XcIAG8QqEDUP3I

 

 

 

# JWT는 언제 사용하나요?

위에서 언급하였듯, 서버와 클라이언트 사이에서 인증 정보를 주고받을 때 사용합니다.

더 구체적으로 이야기 해보자면,

  • 로그인 후 인증 상태 유지 (세션 대신)
  • API 서버에서 사용자 인증 처리
  • 권한 체크(예: 관리자만 접근 가능한 페이지)

이런 상황들이 있습니다.

 

 

# JWT를 어떻게 사용하나요?

JWT를 통해 우리가 '인증/인가'를 다룰 때에는 주로 Access Token과 Refresh Token을 만들어 사용합니다.

 

- 왜?

보안적인 측면이 큽니다.

Access Token은 짧은 시간만 유효하기 때문에 유출되더라도 피해를 최소화할 수 있고,

Refresh Token은 백그라운드에서 새로운 Access Token을 발급받기 위해 사용됩니다.

 

항목 Access Token Refresh Token
용도 인증된 사용자임을 증명 새로운 Access Token 발급 요청
수명 짧음 (보통 5~15분) 김 (보통 7일~30일)
사용 위치 Authorization 헤더에 포함 (Bearer) 주로 HttpOnly 쿠키에 저장
보안 사고 시 영향 API 직접 접근 가능 → 위험 Access Token 계속 재발급 가능 → 더 위험
서버 저장 필요 여부 ❌ (Stateless) ✅ (DB, Redis 등으로 관리하는 것이 일반적)
재발급 가능 여부 불가능 가능 (Access Token 재발급용)
로그아웃 시 조치 클라이언트에서 삭제 서버에서 블랙리스트 처리 or DB에서 제거 필요

 

# 실제 사용 예시

저희 서비스에서는 어떻게 동작하는지 알아봅시다.

 

1. 로그인 시

  1. 클라이언트가 아이디/비밀번호로 로그인 요청
  2. 서버에서 사용자 인증 성공 시:
    • Access Token은 Authorization 헤더로, Refresh Token은 HttpOnly 쿠키를 통해 전달
    • Refresh Token은 HttpOnly 쿠키에 저장

2. API 요청 시

  1. 클라이언트는 Authorization: Bearer <Access Token> 헤더로 API 요청
  2. 서버는 Access Token을 검증하고 요청을 처리
    • Access Token이 유효하면 → 요청 정상 처리
    • Access Token이 만료되었으면 → 아래로

3. Access Token 만료 시 (자동 재발급)

  1. 클라이언트가 자동으로 Refresh Token을 사용해 /api/auth/refresh-token에 요청
  2. 서버는 Refresh Token을 검증하고:
    • 유효하다면 새로운 Access Token 재발급
    • 선택적으로 Refresh Token도 재발급 (Rotation 적용 시)
  3. 클라이언트는 새 Access Token으로 API 요청 재시도

4. 로그아웃 시

  • 클라이언트:
    • 저장된 Access Token 제거
  • 서버:
    • Refresh Token을 DB/Redis에서 삭제

 

이렇게 저희 인증 방식이 진행되고 있습니다.

한동안 백엔드 친구와 Token을 어떻게 보내는지에 대해 이야기를 나눴었는데, 이번 경험으로 JWT에 대해 더 자세히 알아보았던 것 같습니다.

틀리거나 더 나은 방법이 있다면 언제든 피드백 주시면 감사드리겠습니다!

728x90

'G-PBL' 카테고리의 다른 글

근황  (2) 2025.02.26
G-PBL 후반전  (0) 2025.02.14
면접 후기 4  (0) 2025.02.12
면접 후기 3  (3) 2025.02.11
팀 터짐 ㅋㅋ  (0) 2025.01.19