Swift

[iOS] About JWT(Jason Web Token)

dsungc 2024. 10. 17. 06:43

 

JWT

유저를 인증하고 식별하기 위한 토큰 기반 인증 방식

주로 인증 및 정보 전달을 위해 사용

토큰을 클라이언트에 저장하고 요청 시 HTTP 헤더에 토큰을 첨부하는 것만으로 간단하게 데이터를 요청하고 응답 가능

 

 

JWT 구성

JWT 구조(BizSpring)

 

1. Header



토큰의 타입과 해싱 알고리즘 정보 기입

kid: 서명 시 사용하는 키를 식별하는 값

typ: 토큰 유형

alg: 해싱 알고리즘

 

2. Payload

 

토큰에서 사용할 정보의 조각들인 클레임(key-value 형태)이 담겨 있음

Registered Claim: exp(만료시간), sub(제목), iss(발급자) 등 표준 클레임

Public Claim: 사용자 정의 데이터

Private Claim: 비공개 데이터

 

3. Signature

 

헤더에서 정의한 알고리즘 방식 활용

헤더와 페이로드를 조합해 비밀키로 서명하여 생성 → 데이터 무결성 확인

 

JWT의 등장 배경: 세션 기반 인증의 한계

 

세션 기반 인증의 단점

 

1. 유저 확인 시 DB에 접근하여 세션 ID를 조회하는 작업 필요

2. 별도의 저장 관리가 필요하며, 상태를 저장하기 때문에 서버가 사용자의 상태를 계속 추적해야 함

3. 확장성 문제: 대규모 서비스에서 서버 부하 증가

 

JWT의 장점

1. 무상태성: 서버의 부담 감소

2. 여러 서비스 간 인증 연동 가능

3. 보안성 증가: Signature를 공통키 또는 개인키 암호화를 통해 데이터 위·변조 방지

 

JWT의 단점

1. 탈취의 위험

JWT는 서버가 상태를 저장하지 않으므로, 한 번 발급된 토큰은 만료되기 전까지 클라이언트가 자유롭게 사용 가능

토큰이 탈취되었을 경우, 제3자가 이를 악용해 인증된 사용자로 가장 가능

2. 토큰 탈취 시나리오

Man-in-the-Middle (MITM): HTTPS를 사용하지 않는 경우 네트워크에서 토큰이 탈취될 수 있음

XSS 공격: 브라우저 스크립트를 통해 로컬 스토리지 또는 쿠키에 저장된 토큰이 노출될 수 있음

토큰 스니핑: 민감한 정보가 포함된 토큰을 안전하지 않은 장소에 저장하거나 로그로 출력할 경우 유출 가능

 

대안: 액세스 토큰과 리프레시 토큰

 

1. 액세스 토큰 (Access Token)

 

목적: 클라이언트가 리소스 서버에 요청을 보낼 때 인증 수단으로 사용

특징:

유효기간이 짧게 설정됨 (예: 5~15분)

유출되더라도 짧은 시간 안에 무효화되므로 피해를 최소화 가능

사용 방식:

클라이언트는 요청 시 HTTP Authorization 헤더에 액세스 토큰을 첨부

 

2. 리프레시 토큰 (Refresh Token)

 

목적: 액세스 토큰이 만료되었을 때 새로운 액세스 토큰을 발급받기 위해 사용

특징:

유효기간이 길게 설정됨 (예: 7일~30일)

서버가 상태를 저장하여, 필요한 경우 특정 리프레시 토큰을 강제로 무효화 가능

클라이언트가 리프레시 토큰을 사용하여 새 액세스 토큰을 발급받는 동안 민감한 정보를 보호 가능

사용 방식:

1. 클라이언트는 만료된 액세스 토큰과 리프레시 토큰을 서버에 전송

2. 서버는 리프레시 토큰의 유효성을 검증하고, 새로운 액세스 토큰을 발급

3. 리프레시 토큰이 만료된 경우, 클라이언트는 다시 로그인

 

액세스 토큰 + 리프레시 토큰의 장점

1. 보안성 향상

탈취된 액세스 토큰은 유효기간이 짧아 피해가 제한적

리프레시 토큰은 서버에서 관리하거나 추가 검증을 거치므로 보안 위험 감소

2. 유연한 무효화

리프레시 토큰을 서버에 저장하고, 필요 시 개별 사용자의 토큰을 무효화 가능

3. 사용자 경험 개선

사용자는 액세스 토큰이 만료되어도 다시 로그인하지 않아도 됨

리프레시 토큰을 사용해 새 액세스 토큰을 자동으로 발급받아 무중단 인증 가능

 

액세스 토큰과 리프레시 토큰 사용 플로우

1. 사용자가 로그인을 시도하면 서버는 액세스 토큰리프레시 토큰을 발급

2. 클라이언트는 액세스 토큰을 이용해 API 요청

3. 액세스 토큰이 만료되면, 리프레시 토큰으로 새로운 액세스 토큰을 요청

4. 서버는 리프레시 토큰의 유효성을 검증하고, 새 액세스 토큰을 발급

5. 리프레시 토큰이 만료된 경우, 사용자는 다시 로그인