1. Token의 역할과 특징
토큰은 HTTP의 상태 비저장성을 보완하고, 사용자 인증, 세션 관리, 권한 부여를 보다 안전하게 관리하기 위해 웹 애플리케이션에서 사용됩니다. 주로 클라이언트와 서버 간 인증 및 통신 과정에서 사용됩니다.
- 주요 기능
- 인증 (Authentication): 사용자가 누구인지 확인하고, 그 사용자가 시스템에 접근할 수 있는 권한을 서버에 알림.
- 세션 관리 (Session Management): 각 요청에 토큰을 포함해 사용자 세션을 관리. 이 방식은 서버 확장성과 무관하게 작동하여 서버 부담을 줄임.
- 권한 부여 (Authorization): 토큰에 사용자의 권한 정보가 담겨 있어, 서버는 해당 사용자의 접근 권한을 쉽게 판단할 수 있음.
- 보안 (Security): 토큰은 서명(Signature)을 포함하여 변조 방지 및 무결성을 보장하고, CSRF(Cross-Site Request Forgery)와 같은 공격으로부터 보호 가능.
2. JWT의 구성 요소와 구조
JWT (JSON Web Token)는 세 가지 주요 요소 (Header, Payload, Signature) 로 이루어져 있으며, 점(.)으로 구분되어 header.payload.signature
형식으로 구성됩니다.
Header
- 토큰 유형과 서명에 사용되는 암호화 알고리즘 정보를 포함.
- 보통
typ
(토큰 타입, JWT)와alg
(암호화 알고리즘, HS256) 두 가지 정보로 구성됨.
{ "alg": "HS256", "typ": "JWT" }
Payload
- 클레임(Claims)이라고 불리는 인증, 권한 부여와 관련된 사용자 정보가 담김.
- 주요 클레임:
- 등록된 클레임 (Registered Claims): JWT 표준에 정의된 클레임, 예를 들어
iss
(발급자),exp
(만료 시간),sub
(주제, 사용자 ID). - 공개 클레임 (Public Claims): 서비스 간 상호 운영을 위해 IANA에 등록되거나 URL 형태로 정의됨. 예를 들어
role
,email
. - 비공개 클레임 (Private Claims): 두 시스템 간에 협의된 클레임으로, 보통 사용자별 세부 정보를 담음.
- 등록된 클레임 (Registered Claims): JWT 표준에 정의된 클레임, 예를 들어
{ "sub": "1234567890", "name": "John Doe", "admin": true }
Signature
- 헤더와 페이로드를 각각 Base64URL로 인코딩하여 서버의 비밀 키로 서명해 JWT의 무결성을 보장.
- 서버는 이 서명을 통해 클라이언트가 전송한 JWT가 변조되지 않았음을 확인할 수 있음.
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
3. JWT 사용 과정
JWT는 보통 클라이언트와 서버 간의 인증 및 정보 교환 과정에서 사용됩니다. 인증 과정에서 사용자는 ID와 비밀번호를 통해 인증을 시도하고, 서버는 이를 검증한 후 JWT를 발급해 클라이언트에 반환합니다.
- JWT 발급: 사용자가 로그인하면 서버가 사용자의 인증 정보를 확인하고 JWT를 생성하여 클라이언트에 전달.
- 토큰 저장: 클라이언트는 이 토큰을 로컬 스토리지나 세션에 저장하고, 추후 요청에 사용할 수 있도록 관리.
- 요청 시 토큰 전송: 클라이언트는 요청마다
Authorization: Bearer <토큰>
형식으로 서버에 전송하여 인증을 대신함. - 서명 검증 및 만료 확인: 서버는 클라이언트가 전송한 JWT의 서명과 만료 시간을 검증하여, 유효한 토큰인지 확인.
- 리프레시 토큰 갱신: 만료된 토큰의 경우, 리프레시 토큰을 통해 새로운 액세스 토큰을 발급받아 계속 사용할 수 있음.
4. JWT의 장점
- 자가 포함된 구조 (Self-contained): JWT는 필요한 정보를 자체적으로 포함하므로, 서버가 상태 비저장(stateless) 상태를 유지 가능.
- 간결함 (Compactness): JSON 형식을 Base64URL로 인코딩하여 크기가 작아 네트워크 오버헤드가 적음.
- 모바일 친화성: 모바일 환경에서 클라이언트가 저장하고 네트워크 연결이 가능할 때만 서버에 전송하면 되어, 세션 유지 부담을 줄일 수 있음.
- 크로스 도메인 인증: JWT는 특정 도메인에 의존하지 않고, CORS 정책을 지원해 크로스 도메인 요청에서도 사용 가능.
- 확장성: 서버가 사용자 세션을 직접 관리하지 않아 서버 확장이 용이함.
5. JWT의 단점과 보완 방법
- 보안 문제: Base64로 인코딩된 정보는 누구나 읽을 수 있어 민감 정보를 담아서는 안 됨. 민감 정보는 별도의 안전한 저장소에서 관리.
- 토큰 길이 문제: Self-contained 구조로 인해 많은 데이터가 포함될수록 토큰이 길어질 수 있음. 필요한 최소한의 정보만 포함하도록 설계.
- 상태 관리의 어려움: 토큰을 강제로 만료시키기 어려워 보안이 복잡. 주기적인 토큰 갱신과 짧은 만료 시간 설정이 필요.
- 재사용 공격 위험: HTTPS를 통해 안전하게 전송하고, 클라이언트 측에서도 안전한 위치에 저장 필요.
6. 보안 고려 사항
- 서명 검증: 클라이언트가 보낸 JWT는 서버가 서명을 검증하여 변조되지 않았음을 확인해야 함.
- 만료 시간 설정: JWT의
exp
클레임을 통해 만료 시간을 설정하고, 만료된 토큰은 서버에서 거부함으로써 보안을 강화. - HTTPS 사용: 탈취 위험을 방지하기 위해 HTTPS 프로토콜로 전송하여 암호화 필요.
- 저장 위치: 클라이언트가 토큰을 안전하게 저장하도록 HttpOnly 및 Secure 설정을 권장.
7. JWT 활용 사례
- 인증 (Authentication): 클라이언트가 JWT를 통해 본인의 신원을 인증하여 요청을 전송할 수 있음.
- 권한 부여 (Authorization): 서버는 토큰의 권한 정보로 사용자가 특정 리소스에 접근할 수 있는지를 판단.
- 정보 교환 (Data Exchange): 서버 간, 또는 클라이언트와 서버 간 안전한 데이터 전송 가능.
JWT는 웹 애플리케이션에서 인증, 권한 부여, 세션 관리 등 다양한 보안 요구사항을 만족하는 효과적인 방법으로, 특히 상태 비저장 방식으로 확장성과 보안성을 동시에 높여줍니다.
'Springboot Study > Springboot Security' 카테고리의 다른 글
CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유) (0) | 2024.11.01 |
---|---|
CSRF(Cross-Site Request Forgery) (0) | 2024.10.31 |
Filter (FilterChain) (0) | 2024.10.31 |
Spring Security에서 중요한 인터페이스들 (0) | 2024.10.30 |
스레드풀 (0) | 2024.10.29 |