JWT 토큰 인증 이란?

2025. 3. 25. 21:16·Backend/Spring

인증(Authentication)과 인가(Authorization)

✅ 인증 (Authentication)

사용자의 신원을 확인하는 작업이다.

✅ 인가(Authorization)

인증된 사용자가 특정 리소스에 대한 접근 권한을 가지고 있는지 확인하는 과정으로 “어서와 ~” 로 기억해보자 !

JWT의 경우, 사용자의 신원을 나타내는 정보를 안전하게 클라이언트와 서버 간에 주고받기 위한 방식으로 설계되었으므로 “인증”의 개념과 더 밀접하게 연관이 있다.

JWT (Json Web Token) 이란 ?

JWT(JSON Web Token)란 인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미한다. 그리고 JWT 기반 인증은 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식이다

JWT 구조

JWT는 . 을 구분자로 나누어지는 세 가지 문자열의 조합이다.
. 을 기준으로 좌측부터 Header, Payload, Signature를 의미한다.

https://jwt.io/ 에서 서버에서 생성한 JWT를 넣기만 해도 볼 수 있는 화면이다. JWT에서 header와 payload는 특별한 암호화 없이 흔히 사용할 수 있는 base64 인코딩을 사용하기 때문에 서버가 아니더라도 그 값을 확인할 수 있다.

 

☑️ Header

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

{
  "alg": "HS256",
  "typ": "JWT"
}

 

☑️ Payload

토큰에서 사용할 정보의 조각들인 Claim(key-value 형식으로 이루어진 한 쌍의 정보)이 담겨있다. 서버와 클라이언트가 주고 받는 시스템에서 실제로 사용될 정보에 대한 내용을 담고 있다.

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Claims의 종류

  • Registered Claims : 미리 정의된 Claims
    • iss(issuer) : 발행자
    • exp(expiration time) : 만료시간
    • sub(subject) : 제목
    • iat(issued At) : 발행 시간
    • jti(JWT ID) : 토큰의 고유 식별자
  • Public Claims : 사용자가 정의할 수 있는 클레임, 공개용 정보 전달 목적
  • Private Claims : 사용자 지정 클레임, 당사자들 간에 정보를 공유하기 위한 목적

 

☑️ Signature

헤더에서 정의한 알고리즘 방식(alg)를 활용한다. Signature는 header와 payload를 디코딩한 값을 합치고 이를 your-256-bit-secret, 즉 서버가 가지고 있는 개인키로 암호화된 상태다.

따라서 Signature는 서버에 있는 개인키로만 암호화를 풀 수 있고 다른 클라이언트는 임의로 Signature를 복호화할 수 없다.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
    your-256-bit-secret
) secret base64 encoded

base64UrlEncode는 값을 URL에서 사용할 수 있도록 +, /를 각각 -, _로 표기한다.

Header와 Payload는 Encoding된 값이기 때문에 복호화 혹은 값을 수정할 수 있지만 Signature는 서버에서 관리하는 값이기 때문에 Secret Key가 유출되지 않는 이상 복호화 할 수 없다.

JWT를 이용한 인증 과정

1️⃣ 클라이언트가 로그인 요청

  • 사용자가 아이디와 비밀번호 등의 인증 정보를 입력하여 POST 요청을 통해서버로 전송한다.
POST /login HTTP/1.1
Content-Type: application/json
{
    "username": "user123",
    "password": "securepassword"
}

 

2️⃣ 서버에서 사용자 정보 확인 및 JWT 생성

  • 서버는 전달받은 사용자 정보를 DB에서 확인하여 사용자를 인증한다.
  • 인증 성공 시 사용자의 신원을 나타내는 정보(Header, Payload, Signature)를 담아 JWT를 생성하고 Access Token과 Refresh Token을 발급한다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VySWQiOiJ1c2VyMTIzIiwidXNlcm5hbWUiOiJKb2huIERvZSIsImV4cCI6MTcxMDIzNDU2NywiaWF0IjoxNzEwMjMwOTY3fQ.
0FHwVL3JpcyV5zxkXHcHyiycmEKb2h_yIk6sS0ebqD0

 

3️⃣ 서버가 클라이언트에게 JWT 발급(전달)

  • 서버는 생성된 Access Token 과 Refresh Token 을 클라이언트에게 반환한다.
  • 클라이언트는 받은 JWT를 저장한다. (보통 Local Storage, 쿠키, 또는 Secure Storage 사용)
HTTP/1.1 200 OK
Content-Type: application/json

{
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

 

4️⃣ 클라이언트가 이후 요청에 JWT 포함

  • 클라이언트는 인증이 필요한 요청 시, 서버에서 발급받은 JWT를 HTTP 헤더의 Authorization 헤더에 담아 서버에 보낸다.

GET /user/profile
Authorization: Bearer <JWT토큰값>

 

5️⃣ 서버가 JWT 검증 후 인증 처리

  • 서버는 클라이언트의 요청을 받을 때마다 JWT를 검증한다.

JWT 검증 과정은 다음과 같다.

✅ 서명(Signature) 검증 : 서버가 가지고 있는 비밀키로 JWT 서명을 검증하여 변조되지 않았는지 확인

✅ 유효기간(expiration time, exp) 검증 : 토큰이 만료되었는지 확인

✅ 필요한 사용자 정보가 JWT에 존재하는지 확인(선택적)

 

JWT 유효성 검증 절차

  1. A의 JWT를 B가 탈취
  2. B가 탈취한 JWT를 임의로 수정
  3. B가 수정한 JWT로 Server에 요청
  4. 서버는 Signature를 사용하여 유효성 검사(Signature 불일치)
    • Header, Payload를 서버의 Secret Key값을 이용해 Signature를 다시 만들어 비교한다.
    • 임의로 조작된 데이터를 판별할 수 있다.

6️⃣ Access Token 만료 시 Refresh Token으로 갱신

  • 만약 Access Token이 만료되었다면 클라이언트는 Refresh Token 을 이용하여 새로운 Access Token 을 요청한다.
POST /auth/refresh
{
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

더 자세한 내용은 해당 동영상을 참고하면 된다.

https://www.youtube.com/watch?v=1QiOXWEbqYQ

https://www.youtube.com/watch?v=XXseiON9CV0

 

JWT의 장단점 및 한계

JWT의 장점

  1. Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있다.
  2. 인증 정보에 대한 별도의 저장소가 필요없고, 클라이언트 인증 정보를 저장하는 세션과 다르게 서버는 무상태가 되어 서버 확장성이 우수해질 수 있다.
  3. OAuth의 경우, 소셜 계정을 이용하여 다른 웹 서비스에서도 로그인이 가능하다.
  4. 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다. (쿠키와의 차이점)

JWT의 단점 및 한계

  1. base64 인코딩을 통한 정보를 전달하므로 전달량이 많다. 따라서 네트워크 전달 시 많은 데이터 양으로 부하가 생길 수 있다.
  2. Payload는 암호화가 되어있지 않으므로 민감 정보를 저장할 수 없다.
  3. 토큰이 탈취당하면 만료될 때까지 대처가 불가능하다.

AccessToken과 RefreshToekn

JWT 토큰이 탈취 당했을 경우, 서버는 토큰의 주인인 클라이언트와 토큰을 탈취한 도둑을 구분할 수 없다. 따라서 유효 기간을 둔다. 그러나 유효기간을 짧게 두면 사용자가 로그인을 자주 해야하므로 사용자 경험적으로 좋지 않고, 유효기간을 길게 두면 보안상 탈취 위험에서 벗어날 수 없다.

따라서 유효기간이 다른 JWT 토큰 두 개, AccessToken과 RefreshToekn이 등장했다.

기본적인 개념

  • Access Token의 유효기간은 짧다. (ex. 60일(마이크로소프트), 1시간(아마존))
  • Refresh Token의 유효기간은 길다. (ex. 1년 (마이크로소프트))
  • 평소에 API 통신할 때는 Access Token을 사용하고, Refresh Token은 Access Token이 만료되어 갱신될 때만 사용한다.

구체적인 동작과정

1️⃣사용자 로그인 요청 (POST /login)

사용자가 아이디와 비밀번호를 입력하여 서버에 로그인 요청을 보낸다.

 

2️⃣Access Token + Refresh Token 발급

서버는 사용자를 인증한 후, Access Token과 Refresh Token을 발급한다.

  • Access Token: 유효 기간이 짧아(수 분~수 시간) 보안성이 높음
  • Refresh Token: 유효 기간이 길며(수 일~수 주), Access Token이 만료될 경우 새로운 Access Token을 발급하는 데 사용됨

클라이언트는 Access Token을 저장하여 이후 API 요청에 사용합니다.

 

3️⃣ API 요청 시 Access Token 사용 (GET /user/profile)

사용자는 로그인이 완료된 후, 프로필 조회와 같은 API 요청을 보낼 때 Authorization 헤더에 Access Token을 포함하여 서버에 요청을 보낸다.

 

4️⃣ 서버에서 Access Token 검증

서버는 요청을 받으면 Access Token이 유효한지 확인한다.

  • 유효한 경우 : 정상적으로 요청을 처리하고 데이터를 반환한다.
  • 만료된 경우: 클라이언트에게 만료되었음을 응답하고 Refresh Token을 사용하여 새 Access Token을 요청하도록 안내한다.

5️⃣ Access Token 만료 시, Refresh Token을 이용해 새 Access Token 요청 (POST /auth/refresh)

클라이언트는 만료된 Access Token을 삭제하고, Refresh Token을 포함하여 새로운 Access Token을 요청한다.

 

6️⃣ 서버에서 Refresh Token 검증 후 새로운 Access Token 발급

서버는 Refresh Token이 유효한지 확인한 후, 새로운 Access Token을 생성하여 클라이언트에게 반환한다.

  • Refresh Token도 만료되지 않았다면 새로운 Access Token을 발급한다.
  • 만약 Refresh Token이 만료되었거나 유효하지 않다면, 사용자는 다시 로그인해야한다.

7️⃣ 새로운 Access Token을 사용하여 API 요청 (GET /user/profile)
클라이언트는 발급받은 새로운 Access Token을 저장한 후, 다시 API 요청을 보낸다.

이후부터는 새로운 Access Token을 이용하여 정상적인 API 요청을 수행할 수 있다.

 

8️⃣ Refresh Token도 만료된 경우 → 재로그인 필요
만약 Refresh Token도 만료되었다면, 서버는 더 이상 새 Access Token을 발급해주지 않고,사용자가 다시 로그인해야 함을 응답한다.

사용자는 재로그인하여 새로운 Access Token과 Refresh Token을 받아야 한다.

'Backend > Spring' 카테고리의 다른 글

ServiceHelper를 통한 Service 코드 책임 분리  (0) 2025.04.01
BaseTimeEntity와 JPA Auditing: 왜 사용할까?  (0) 2025.04.01
JPA와 영속성 컨텍스트  (0) 2025.03.31
[Spring 기초] 일정 관리 앱 만들기  (0) 2025.03.26
쿠키 세션 토큰 비교하기  (0) 2025.03.24
'Backend/Spring' 카테고리의 다른 글
  • BaseTimeEntity와 JPA Auditing: 왜 사용할까?
  • JPA와 영속성 컨텍스트
  • [Spring 기초] 일정 관리 앱 만들기
  • 쿠키 세션 토큰 비교하기
yeunever
yeunever
yeunever 님의 블로그 입니다.
  • yeunever
    yeunever 님의 블로그
    yeunever
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
        • 데이터베이스
        • Linux
        • 네트워크
        • 운영체제
      • Backend
        • Spring
        • Web
      • 개발
        • 기능 구현
        • Trouble Shooting
      • 자격증
        • SQLD
        • ADSP
        • 정보처리기사
      • Language
        • Java
      • DevOps
      • 회고
      • TIL
      • Frontend
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    단위 테스트
    cube
    no supported authentication methods available (server sent: publickey
    세션
    sqld
    #소프트웨어테스트
    #sw테스트
    ssh 접속 오류
    토큰
    EC2
    #sqld시험일정 #sqld자격증 #sqld노랑이 #sqld독학 #sqld책 #sqld시험 #sqld접수 #sqld유효기간 #sqlp #sqld노랭이 #데이터자격증 #sql개발자 #데이터모델링 #sql #mysql #오라클 #데이터자격시험 #한국데이터산업진흥원
    GROUPING
    통합 테스트
    known_hosts
    puTTY
    pem
    2과목
    rollup
    groupingsets
    정보처리기사 필기
    블랙박스 테스트
    컴퓨터네트워크
    화이트박스 테스트
    #테스트개발
    쿠키
    단편화
    그룹함수
    정보처리기사
    #sqld #sqld시험일정 #sqld자격증 #sqld노랑이 #sqld독학 #sqld책 #sqld시험 #sqld접수 #sqld유효기간 #sqlp #sqld노랭이 #데이터자격증 #sql개발자 #데이터모델링 #sql #mysql #오라클 #데이터자격시험 #한국데이터산업진흥원
    PPK
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
yeunever
JWT 토큰 인증 이란?
상단으로

티스토리툴바