JWT(JSON Web Token)
- 서버와 클라이언트 간의 정보를 안전하게 전달하기 위해 사용되는 토큰 기반의 인증 방식
- 텍스트 기반의 토큰 → 정보를 JSON 형식으로 인코딩하여 사용자 정보나 권한 정보를 포함
- 클라이언트가 서버로 요청을 보낼 때마다 헤더에 첨부되어 전송 → 서버는 해당 토큰을 검증하여 인증 및 권한을 확인
JWT의 구성 요소
- Header
- 토큰의 베타 정보를 담고 있다.
- 주로 토큰의 유형과 서명 알고리즘을 명시
- Base64로 인코딩되어 토큰의 첫 부분을 형성
{
"typ": "JWT",
"alg": "HS256"
}
- Payload
- 클라이언트 정보나 클레임(Claim) 정보 포함
- 클레임 : 사용자 정보, 토큰의 만료 기간, 권한 등 포함
- Base64로 인코딩되어 토큰의 두 번째 부분을 형성
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
- Signature
- 토큰의 위변조 여부를 확인하기 위해 사용되는 부분
- 헤더, 페이로드, 서버의 비밀 키를 이용하여 서명되며, 클라이언트가 서버로부터 받은 토큰의 무결성을 검증할때 사용
Claim
JWT 내에서 사용자에 대한 정보나 추가적인 메타데이터를 나타내는 key-value 쌍이다.
1. 등록된 클레임(Registered Claims)
- iss : 토큰 발급자(issuer)
- sub : 토큰 주제(subject)
- aud : 토큰 대상자(audience)
- exp : 토큰 만료 시간(expiration time)
- nbf : 토큰 활성 시작 시간(not before)
- iat : 토큰 발급 시간(issued at)
- jti : JWT 고유 식별자(JWT id)
- alg : 서명의 알고리즘
- typ : 토큰의 유형(type)
2. 공개 클레임(Public Claims)
사용자가 필요에 따라 추가할 수 있는 클레임으로, 충돌을 방지하기 위해 클레임명을 URI 형태로 정의하는 것이 권장된다.
3. 비공개 클레임(Private Claims)
클라이언트, 서버의 합의하에 사용되는 클레임 이름들이다. 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있다.
JWT 인증 흐름
- 클라이언트 로그인
- 서버는 해당 계정 정보를 읽어 사용자가 있는지 확인하고, JWT 토큰 발급
- 서버는 secret_key를 이용해 발급한 Access Token을 클라이언트에게 전달
- 클라이언트는 해당 Access Token을 저장한 후, 인증이 필요한 요청마다 Authorization 헤더에 토큰을 추가하여 요청
- 서버는 secret_key를 이용해 해당 토큰의 Verify Signature를 복호화한 후, 조작 여부와 유효기간 확인
if 사용할 수 없는 토큰이라면 서버에 있는 Refresh Token으로 새로운 Access Token 발급 - 검증이 완료되면 Payload를 디코딩하여 사용자 데이터를 전달
JWT 장단점
JWT 장점
- Stateless 서버
- 기존의 세션 기반 인증 방식에서는 서버가 각 클라이언트의 세션 상태를 유지해야 했다. → 서버 부하를 유발하고, 확장성이 제한되는 문제를 일으킬 수 있다.
- 하지만 JWT는 토큰 자체에 필요한 정보를 포함하고 있기 때문에 서버는 별도의 상태를 유지하지 않아도 되며, Stateless 서버 아키텍처를 구현할 수 있다.
- 인프라 비용 절감
- 세션 기반 방식에서는 사용자의 세션 정보를 저장하고 관리하는데 DB나 캐시 등의 인프라가 필요하다.
- 이에 비해 JWT는 서버에서 토큰을 검증만 하면 되기 때문에 데이터베이스 조회나 인프라 관리에 따른 비용과 시간을 절감할 수 있다.
- 분산 시스템 지원
- JWT는 서버 간에 토큰을 전달하는 방식이므로 여러 서비스 간에 사용자 인증 정보를 공유하기에 용이하다.
- 따라서 분산 시스템이나 MSA에서 각 서비스 간의 인증을 위해 중앙 집중식 인증 서버가 필요 없어진다.
- CORS 해결
- 쿠키를 사용하면 발생하는 CORS 문제를 해결할 수 있다
- 웹 애플리케이션에서 다른 도메인의 API를 호출하려고 할 때, 브라우저는 보안 상의 이유로 이 요청을 차단한다. 이로 인해 Cross-Origin Reqeust Blocked와 같은 오류가 발생할 수 있다.
- JWT를 이용하면 클라이언트 측에서는 토큰을 사용하여 인증을 처리하므로, 서버 간의 동일 출처 정책(Same-Origin Policy)를 우회할 필요가 없다.
- CORS란?
- Cross-Origin Resource Sharing의 약어로, 웹 브라우저에서 실행되는 애플리케이션에서 다른 출처(도메인, 포트, 프로토콜)의 리소스에 접근하는 보안 메커니즘을 의미한다.
- 웹 보안을 강화하기 위해 브라우저는 기본적으로 Same-Origin Policy를 따르고 이로 인해 웹 페이지나 애플리케이션이 다른 출처의 리소스에 접근하는 것을 제한하게 된다.
- 쿠키를 사용하면 발생하는 CORS 문제를 해결할 수 있다
JWT 단점
- 보안
- JWT 토큰이 탈취되어 악의적으로 사용된다면 막을 방법이 없다. 세션/쿠키의 경우 악용되는 세션을 지우면 되지만, JWT 토큰은 유효기간이 끝날때까지 토큰을 삭제하거나 변경할 방법이 없기 때문이다.
- Payload는 누구나 디코딩할 수 있기 때문에 중요한 정보를 넣을 수 없으므로 토큰에 저장할 수 있는 정보가 제한된다.
- 세션/쿠키 방식에 비해 JWT의 길이가 길다. 따라서 인증이 필요한 요청이 많다면 서버의 자원낭비가 발생한다.
- 로그아웃 처리
- 로그아웃 시 클라이언트 측에서는 로그아웃이 되었지만 Stateless(무상태) 특성 때문에 서버에 저장된 토큰의 로그아웃 처리가 어렵다.
JWT 사용 시 고려 사항
- Claim Set은 암호화되지 않고 Base64로만 인코딩되기 때문에, 여기에 민감한 정보를 포함시키면 보안에 취약할 수 있다.
- Claim Set의 내용이 많아지면 토큰의 길이도 길어지기 때문에 너무 많은 정보를 담으면 안 된다.
- 토큰이 탈취될 경우를 대비하여 Access Token의 유효기간은 짧게 설정하고 Refresh Token을 사용하여 새로운 Access Token을 발급받는 방식을 활용하는 것이 좋다.
예상 질문
- JWT가 무엇인가요?
- JWT의 구조는 어떻게 되나요? 각 부분의 역할은 무엇인가요?
- JWT의 장점은 무엇인가요?
- JWT의 단점은 무엇인가요?
- JWT와 세션 기반 인증 방식의 차이점은 무엇인가요?
- JWT의 작동 원리를 설명해보세요.
- JWT를 사용하는 상황을 어떻게 선택하나요? 어떤 시나리오에서 JWT가 유용한가요?
- JWT의 보안 문제는 무엇인가요? 어떻게 이러한 보안 문제를 해결할 수 있나요?
- JWT의 payload에 어떤 정보를 저장할 수 있나요? 예시를 들어 설명해보세요.
- JWT를 서명하고 검증하는 과정을 설명해보세요.
- JWT를 사용할 때 언제 대칭 키 알고리즘을 선택하는 것이 좋고, 언제 비대칭 키 알고리즘을 선택하는 것이 좋은가요?
- JWT의 유효 기간(Expiration)과 발급 시간(Issued At)의 중요성을 설명해보세요.
- JWT의 캐시 문제와 관련하여 어떤 문제가 발생할 수 있나요? 어떻게 이를 해결할 수 있을까요?
- JWT를 사용한 프로젝트의 경험을 공유해보세요. 어떻게 JWT를 구현하고 어떤 이점을 얻었나요?
- JWT를 만들 때 어떤 라이브러리나 프레임워크를 사용했는지 설명해보세요.
- JWT 리프레시 토큰(Refresh Token)에 대해 설명해보세요. 왜 사용하며 어떻게 작동하나요?
- JWT를 안전하게 저장하고 전송하기 위해 어떤 보안 요법을 사용하는 것이 좋은가요?
- JWT를 사용할 때 발생할 수 있는 보안 위협과 공격 유형은 어떤 것이 있나요?
- JWT를 다루면서 발생한 어려움이나 문제 상황을 언급해보세요. 어떻게 해결했나요?
- JWT와 OAuth 2.0 또는 OpenID Connect와의 관계는 무엇인가요? 어떻게 함께 사용될 수 있을까요?
'Computer Science > Web' 카테고리의 다른 글
[Web] Logging Level (0) | 2023.08.31 |
---|---|
[Web] 인증 방식 (0) | 2023.08.31 |
[Web] OAuth (0) | 2023.08.10 |
[Web] Web Server와 WAS의 차이 (0) | 2023.08.10 |
[Web] REST API (0) | 2023.08.10 |