[Spring] 토큰 기반 인증, JWT

0woy·2025년 1월 26일
0

개발

목록 보기
6/7
post-thumbnail

0. 사용자 인증

사용자가 서버에 접근할 떄 이 사용자가 괜춘한(인증된) 사용자인지 확인하는 방법은
대표적으로 서버 기반 인증토큰 기반 인증이 있다.

스프링 시큐리티에서는 기본적으로 세션 기반 인증 제공한다.
-> 사용자마다 사용자의 정보를 담은 세션 생성 & 저장하여 인증함


1. 토큰 기반 인증

토큰 기반 인증은 말 그대로 토큰 사용

토큰
서버에서 클라이언트를 구분하기 위한 유일한 값

  • 서버가 토큰을 생성해 클라이언트에게 제공
  • 클라이언트는 이 토큰을 갖고 있다가 여러 요청을 토큰이랑 같이 넘김
  • 서버는 토큰만 보고 유효한 사용자인지 검증

1) 토큰을 전달하고 인증받는 과정

출처: 나 자신


2) 토큰 기반 인증의 특징

1. 무상태성

  • 사용자 인증 정보가 담겨있는 토큰이 클라이언트에 있으므로 서버에 저장할 필요 없음
    서버가 데이터를 유지하려면 그만큼 자원을 소비해야 함.

  • 상태 관리를 할 필요가 없어서 완전한 무상태 (stateless) 로 효율적인 검증 가능

    상태 관리
    사용자의 인증 상태를 유지하면서 요청을 처리하는 것

2. 확장성

무상태성은 확장성에 영향을 줌
오ㅐ❓ > 서버를 확장할 때 상태 관리를 신경 안 쓰니까 서버 확장도 쉽게 함

IF. 주문 서버, 결제 서버 IN 물건 파는 서비스

인증법접근
세션각각 API에서 인증 처리해야 함
토큰하나의 토큰으로 결제 서버와 주문 서버에 요청을 보냄

3. 무결성

토큰 방식은 HMAC (Hash-based Message AuthentiCation) 기법이라고도 함
토큰을 발급한 이후, 토큰 정보 변경하는 행위는 할 수 없음

즉, 토큰의 무결성이 보장..
하나라도 바꾸면 서버는 토큰이 유효하지 않다고 판단함


2. JWT란?

  • JWT(JSON Web Token)은 정보를 JSON 객체로 안전하게 전송하는 방법을 정의하는 개방형 표준
  • 크기가 작고, 독립적인 (self-contained) 형태를 가지며,
    디지털 서명을 통해 검증할 수 있어 신뢰 가능
  • 비밀키 (HMAC algorithm) 방식 또는 공개/개인키 (RSA, ECDSA) 방식으로 서명

JSON (JavaScript Object Notation)
데이터를 키-값 (key-value) 쌍으로 구성하는 경량 데이터 형식

  • 사람이 읽기 쉽고, 기계가 빠르게 파싱 가능
  • 웹에서 데이터를 주고 받을 때 많이 사용됨

{ 
  "name": "Alice",
  "age": 25,
  "isStudent": false,
  "skills": ["Java", "Spring Boot", "Vue.js"],
  "address": {
    "city": "Seoul",
    "country": "Korea"
  }
}

JWT를 암호화 하면 기밀성을 포함 할 수 있음 = JWE (Json Web Encryption)

JWT (서명된 토큰)JWE(암호화된 토큰)
기능무결성 검증 (변조 방지)기밀성 제공 (내용 숨김)
Payload 노출누구나 읽을 수 있음암호화 되어 읽을 수 없음
보안성변조 방지변조 방지 + 데이터 보호
예시OAuth2, 인증 토큰민감한 데이터 전송

3. JWT 구조

. 을 기준으로 Header(헤더), Payload(내용), Signature(서명)으로 이루어짐
ex) xxxx.yyyy.zzzz

① Header

헤더는 일반적으로 '토큰 유형 & 사용되는 서명 알고리즘 ' 두 부분으로 구성됨.

{ // 예시
  "alg": "HS256",
  "typ": "JWT"
}

Header는 Base64Url로 인코딩 되어 JWT의 첫 번째 부분을 구성함

Base64Url 인코딩

Base64 인코딩 의 변형된 형태

기존 Base64 인코딩은 URL에 사용 시 문제가 될 수 있는 문자를 포함 할 수 있어서 이른 URL에 적합하게 수정한 것

  • 바이너리 데이터를 아스키 문자열로 변환하는 방법
  • 주로 텍스트나 이미지 등의 데이터를 웹에서 안전하게 전송하기 위해 사용함
  • 일반적으로 6비트씩 64개 문자 사용

② Payload

토큰과 관련된 정보(Claim)를 담음

Claim
엔티티와 추가적인 데이터에 대한 설명
Registerd(등록된), public (공개), private (비공개) claim으로 나뉨

1. Registered Claim

토큰에 대한 정보를 담는 데 사용
JWT는 간결하게 작성 돼야 하므로 클레임 이름은 3글자로 제한

이름설명형식
iss (Issuer)토큰 발급자
sub (Subject)토큰 제목
aud (Audience)토큰 대상자
exp (Expriration)토큰 만료시간, 현재 시간 이후 설정Numeric Data
nbf (Not before)토큰의 활성 날짜, 해당 날짜 전까지 토큰 처리 XNumeric Data
iat (Issued At)토큰이 발급된 시간Numeric Data
jti (Jwt Id)JWT의 고유 식별자대소문자 구분

2. Public Claim

공개되어도 상관 없는 클레임
다른 시스템과의 상호운용성을 위해 사용될 수 있음
다른 시스템과의 충돌을 피하기 위해 유니크한 이름을 가져야 하며, 보통 URI로 작성

3. Private Claim

발급자와 수신자 간에만 의미 있는 클레임
다른 시스템과 공유되지 않으며, 해당 애플리케이션이나 서비스에서만 사용

JWT는 Header와 Payload를 Base64Url로 인코딩 하여 토큰 생성

디코딩이 정말 쉽기때문에, 민감한 정보는 넣지 말아야 함

③ Signature

해당 토큰이 조작되었거나 변경되지 않았음을 확인하는 용도
Header 인코딩 값, Payload 인코딩 값 그리고 비밀키를 사용해 해시 값 생성


글이 길어지면 읽기 싫은 관계로 [Spring] 토큰 기반 인증, JWT 2편 에서 계속...

참고
Introduction to JSON Web Tokens

0개의 댓글

관련 채용 정보