토큰 기반 인증
정의
- 사용자가 인증을 받은 후, 서버가 발급한 토큰을 사용하여 클라이언트가 요청을 인증하는 방식.
- 클라이언트는 서버의 상태를 유지하지 않고, 토큰을 통해 인증 정보를 전달.
특징
- 자체 포함성: 토큰이 필요한 모든 정보를 포함하므로, 서버가 클라이언트의 상태를 유지하지 않음.
- 비교적 간단한 구현: 다양한 프로그래밍 언어와 프레임워크에서 쉽게 지원되어 구현이 간단함.
- 서버 간 인증 지원: 마이크로서비스 아키텍처에서 각 서비스가 독립적으로 인증을 수행할 수 있도록 지원함.
- 상태 비저장 (Stateless): 서버가 클라이언트의 세션 정보를 저장하지 않기 때문에, 서버 재시작 시에도 문제가 발생하지 않음.
- 다양한 클라이언트 지원: 웹, 모바일, IoT 등 다양한 클라이언트에서 사용 가능함.
- 토큰 만료 및 갱신: 일반적으로 토큰에 만료 시간이 있으며, 리프레시 토큰을 통해 새로운 토큰을 발급받을 수 있음.
- 크로스 도메인 인증 지원: CORS와 결합하여 서로 다른 도메인 간의 인증이 용이.
- 다양한 인증 방법 지원: OAuth2, OpenID Connect 등 다양한 인증 프로토콜과 함께 사용할 수 있음.
장점
- 확장성: 여러 서비스 간의 인증 정보를 쉽게 공유 가능.
- 성능: 서버가 상태를 유지하지 않기 때문에 데이터베이스 조회를 줄여 성능이 향상됨.
- 유연성: 다양한 클라이언트와 통합이 용이함.
단점
- 만료 관리 필요: 만료된 토큰을 처리하는 방법이 필요함.
- 비밀 키 관리: 비밀 키가 유출되면 공격자가 유효한 토큰을 생성할 수 있어 시스템의 보안에 위협이 될 수 있음.
서버 기반 인증과 차이점
서버 기반 인증
- 사용자가 로그인한 후, 서버가 세션을 생성하고, 클라이언트가 이 세션 정보를 사용하여 요청을 인증하는 방식.
- 사용자의 상태가 서버에서 관리됨.
특징
- 상태 유지 (Stateful): 서버가 클라이언트의 세션 정보를 유지함.
- 세션 저장소: 세션 정보는 서버의 메모리, 데이터베이스, 또는 분산 캐시에 저장됨.
- 보안성: 세션 정보는 서버에서만 관리되므로 클라이언트가 조작할 수 없음.
- 자동 만료: 세션은 일정 시간이 지나면 자동으로 만료됨.
- 서버 의존성: 서버가 다운되거나 재시작되면 세션 정보가 소실될 수 있음.
- 쿠키 사용: 세션 ID는 클라이언트의 쿠키에 저장되어 자동으로 포함됨.
- 간편한 관리: 서버에서 세션을 쉽게 추적하고 관리할 수 있음.
- 세션 데이터 확장성: 사용자 정보, 권한 등 다양한 데이터를 세션에 저장할 수 있음.
장점
- 높은 보안성: 세션 정보가 서버에서 관리되므로 보안성이 높임.
- 상태 관리 용이: 서버가 클라이언트의 상태를 쉽게 관리할 수 있음.
- 사용자 맞춤형 경험 제공: 세션에 다양한 정보를 저장하여 개인화된 경험을 제공함.
단점
- 서버 상태 의존성: 서버가 세션 정보를 유지해야 하므로 서버의 부하가 증가할 수 있음.
- 확장성 문제: 로드 밸런싱 환경에서 세션 정보를 공유하는 것이 복잡할 수 있음.
- 쿠키 의존성: 클라이언트가 쿠키를 비활성화하면 인증이 불가능해짐.
비교
특성 | 토큰 기반 인증 | 세션 기반 인증 |
상태 관리 | 서버가 상태를 유지하지 않음 | 서버가 세션 정보를 유지함 |
확장성 | 여러 서비스 간 인증 정보 공유 용이 | 로드 밸런싱 환경에서 복잡해질 수 있음 |
저장 위치 | 클라이언트 측(로컬 스토리지, 쿠키 등) | 서버 측(메모리, 데이터베이스 등) |
보안성 | 클라이언트가 토큰을 관리하므로 조작 가능성 있음 | 서버가 세션을 관리하므로 보안성이 높음 |
만료 처리 | 만료된 토큰 처리 필요 | 서버에서 세션 만료 처리 |
사용 용도 | 마이크로서비스, API 인증에 적합 | 전통적인 웹 애플리케이션에 적합 |
JWT(JSON Web Token)
정의
- 토큰 기반 인증의 한 방법
- JSON 객체를 안전하게 전송하기 위한 개방형 표준(RFC 7519)으로, 주로 사용자 인증 및 정보 교환에 사용
- 클라이언트와 서버 간의 정보 전송을 간편하고 안전하게 수행할 수 있도록 설계되어있음.
구조
- JWT는 세 개의 주요 부분으로 구성되어 있으며, 각 부분은 점(.)으로 구분됨.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
1. 헤더 (Header)
- JWT의 유형과 서명 알고리즘을 정의.
- 토큰의 유형: 일반적으로 "JWT"로 설정됨
- 서명 알고리즘: JWT의 서명을 생성하는 데 사용되는 알고리즘. 일반적으로 HMAC SHA256, RSA, 또는 ECDSA 등이 사용됨.
- 일반적으로 JSON 형식으로 작성되며, Base64Url로 인코딩됨.
{
"alg": "HS256",
"typ": "JWT"
}
2. 페이로드 (Payload)
- JWT에 담길 정보를 포함. 이 정보는 클레임(claim)이라고 하며, 주로 사용자의 ID, 이름, 권한 등을 담을 수 있음.
- 클레임의 종류에는 등록된 클레임 (Registered Claims), 공개 클레임 (Public Claims), 비공식 클레임 (Private Claims) 이 있음.
- 등록된 클레임 (Registered Claims): 미리 정의된 클레임으로, JWT의 사용을 표준화.
- iss (발급자): 토큰을 발급한 주체.
- exp (만료 시간): 토큰의 만료 시간을 Unix timestamp로 표시.
- sub (주제): 토큰의 주체.
- aud (대상): 토큰의 수신자.
- nbf (Not Before): 토큰이 유효해지기 시작하는 시간. 이 시간 이전에는 토큰이 유효하지 않음을 나타냄.
- iat (Issued At): 토큰이 발급된 시간. 이 클레임을 통해 토큰의 발급 시간을 알 수 있음.
- jti (JWT ID): JWT의 고유 식별자. 토큰을 추적하거나 취소하는 데 유용.
- roles: 사용자의 역할이나 권한을 담는 커스텀 클레임. 예를 들어, ["admin", "user"]와 같이 설정할 수 있음.
- 공개 클레임 (Public Claims): 사용자 정의 클레임으로, 충돌을 피하기 위해 URI로 이름을 정의해야 함.
- 비공식 클레임 (Private Claims): 특정 애플리케이션 내에서만 사용되는 클레임.
- 등록된 클레임 (Registered Claims): 미리 정의된 클레임으로, JWT의 사용을 표준화.
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}
3. 서명 (Signature)
- 헤더와 페이로드를 인코딩하여 서명을 생성. 이를 통해 JWT의 무결성을 확인할 수 있음.
- 비밀 키 또는 RSA 개인 키를 사용하여 해시를 생성.
HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),your-256-bit-secret)
작동 원리
특징
- 사용자 인증: 사용자가 로그인한 후, 서버는 사용자의 정보를 담은 JWT를 발급하여 클라이언트에게 전달함. 이후 클라이언트는 API 호출 시 이 JWT를 포함하여 인증을 수행함.
- 권한 부여: 사용자의 권한 정보를 담을 수 있어, 이를 기반으로 API 접근을 제어할 수 있음.
-> 사용자의 역할(role)에 따라 접근 가능한 리소스를 제한할 수 있음. - 정보 교환: 서로 신뢰할 수 있는 시스템 간에 정보를 안전하게 전달할 때 사용할 수 있음.
-> 제3의 서비스에서 사용자의 정보를 요청할 때 JWT를 통해 인증과 권한을 확인할 수 있음. - 서드파티 로그인: 소셜 로그인을 구현할 때, JWT를 사용하여 사용자 인증 정보를 안전하게 교환할 수 있음.
-> Google, Facebook 등의 OAuth 2.0 인증 프로세스에서 JWT를 활용함. - API 보안: RESTful API에서 JWT를 사용하여 각 요청의 인증을 수행하고, 토큰의 유효성을 검증하여 보안을 강화할 수 있음.
장점
- 보안성: 서명을 통해 데이터의 무결성을 보장할 수 있음.
- 자체 포함성: 클라이언트는 JWT를 통해 모든 정보를 직접 가지고 있으므로, 세션 정보를 서버가 유지할 필요가 없음.
- 확장성: 여러 서비스 간의 인증 정보를 쉽게 공유할 수 있음. 특히 마이크로서비스 아키텍처에서 유용함.
- 성능: 서버 측의 상태를 저장할 필요가 없기 때문에, 데이터베이스 조회를 줄여 성능을 향상시킬 수 있음.
- 크로스 도메인 인증: 다양한 클라이언트 애플리케이션(웹, 모바일 등) 간에 안전하게 사용할 수 있음.
단점
- 페이로드 노출: Base64Url로 인코딩되지만, 암호화되지 않기 때문에, 페이로드의 내용이 누구에게나 노출될 수 있음. 따라서 민감한 정보를 포함하지 않아야 함.
- 만료 관리: 만료되기 전까지 유효하므로, 세션이 길어질 경우 보안 문제가 발생할 수 있음. 이를 해결하기 위해서는 주기적으로 새로운 JWT를 발급해야 함.
- 비밀 키 관리: 비밀 키는 안전하게 관리해야 하며, 키가 유출되면 해커가 JWT를 생성할 수 있는 위험이 있음.
보안 고려 사항
- HTTPS 사용: 전송할 때는 HTTPS를 사용하여 중간자 공격을 방지해야 함.
- 비밀 키 관리: 비밀 키는 강력하고 안전하게 관리해야 하며, 정기적으로 변경하는 것이 좋음.
- 만료 시간 설정: 적절한 만료 시간을 설정하여, 사용자가 일정 시간 후에 다시 인증하도록 해야 함.
- 토큰 리프레시: 리프레시 토큰을 사용하여 만료된 JWT를 갱신할 수 있음. 이를 통해 보안을 강화하면서 사용자 경험을 개선할 수 있음.
- 서명 알고리즘 선택: 필요에 따라 적절한 서명 알고리즘을 선택해야 하며, RSA나 ECDSA와 같은 비대칭 알고리즘은 높은 보안을 제공함.
- 클레임 검증: 수신할 때, 발급자(iss), 대상(aud), 만료(exp) 등의 클레임을 검증하여 토큰의 유효성을 확인해야 함.
- 토큰 재사용 방지: 만약 사용자가 로그아웃을 원할 때, 서버에서 해당 JWT를 무효화하는 방법을 마련해야 함. 예를 들어, 블랙리스트를 사용하여 만료된 토큰을 관리하고, 로그아웃 시 해당 토큰을 무효화할 수 있도록 해야 함.
- 클레임의 적절한 사용: 페이로드에 포함하는 클레임은 최소화해야 하며, 필요한 정보만 포함하여 보안성을 높여야 함.
- 정기적인 키 교체: 비밀 키를 정기적으로 변경하야 하며, 키가 노출되지 않도록 안전하게 관리해야 함.
JWT를 저장하는 방법
1. 로컬 스토리지 (Local Storage)
- 정의
- 웹 브라우저의 클라이언트 측 저장소로, 도메인별로 데이터를 저장할 수 있음.
- 사용자가 웹 페이지를 닫거나 새로 고침하더라도 데이터는 유지.
- 장점
- 영속성: 사용자가 브라우저를 닫아도 데이터가 유지되므로, 사용자가 자주 방문하는 웹 애플리케이션에서 유용.
- 간편한 접근: JavaScript를 통해 쉽게 데이터를 읽고 쓸 수 있어 개발이 용이.
- 단점
- 보안 취약점: XSS(교차 사이트 스크립팅) 공격에 취약. 악성 스크립트가 로컬 스토리지에 접근하여 JWT를 탈취할 수 있음.
- 동기화 문제: 여러 탭에서 같은 애플리케이션을 사용할 때 데이터가 동기화되지 않으면 문제가 발생할 수 있음.
- 사용 시 고려 사항
- 민감한 정보를 저장하지 않도록 하며, 사용자가 로그인한 후의 토큰만 저장하는 것이 좋음.
- 민감한 정보를 저장하지 않도록 하며, 사용자가 로그인한 후의 토큰만 저장하는 것이 좋음.
2. 세션 스토리지 (Session Storage)
- 정의
- 브라우저의 클라이언트 측 저장소로, 탭이나 브라우저가 열려 있는 동안에만 데이터가 유지.
- 탭이나 브라우저를 닫으면 데이터는 삭제.
- 장점
- 일시적 저장: 세션이 종료되면 데이터가 자동으로 삭제되므로, 세션 기반 애플리케이션에서 유용.
- 보안성: 로컬 스토리지보다 보안성이 높지만 여전히 XSS 공격에 노출될 수 있음.
- 단점
- 데이터 유지 기간: 사용자가 브라우저를 닫으면 데이터가 사라지므로, 지속적인 세션이 필요한 경우에는 적합하지 않음.
- 제한된 용량: 로컬 스토리지와 마찬가지로 저장 용량에 제한이 있음.
- 사용 시 고려사항
- 데이터가 사라져도 문제가 없는 경우에만 사용하고, 여전히 XSS 공격에 대한 방어 조치를 취해야 함.
- 데이터가 사라져도 문제가 없는 경우에만 사용하고, 여전히 XSS 공격에 대한 방어 조치를 취해야 함.
3. 쿠키 (Cookies)
- 정의
- 서버가 클라이언트에 저장하는 작은 데이터 조각으로, HTTP 요청 시 자동으로 전송.
- 클라이언트는 쿠키를 통해 세션이나 사용자 정보를 유지.
- 장점
- 서버 전송 자동화: 쿠키는 HTTP 요청 시 자동으로 포함되므로, 서버 인증에 유용.
- 보안 설정 가능: HttpOnly 플래그를 설정하면 JavaScript에서 쿠키에 접근할 수 없고, Secure 플래그를 설정하면 HTTPS 연결에서만 쿠키가 전송.
- 단점
- 크기 제한: 쿠키는 일반적으로 4KB 이하의 데이터를 저장할 수 있어 크기에 제한이 있음.
- CSRF 공격: 쿠키는 CSRF(크로스 사이트 요청 위조) 공격에 취약할 수 있으므로, 이를 방지하기 위한 추가적인 보안 조치가 필요
- 사용 시 고려 사항
- 민감한 정보는 쿠키에 저장하지 않으며, 적절한 보안 플래그를 설정하여 XSS와 CSRF 공격에 대비
- 민감한 정보는 쿠키에 저장하지 않으며, 적절한 보안 플래그를 설정하여 XSS와 CSRF 공격에 대비
4. 서버 측 저장소
- 정의
- JWT를 서버의 데이터베이스나 메모리 캐시에 저장하는 방법.
- JWT를 클라이언트에 저장하지 않고 서버에서 관리.
- 장점
- 보안성: 서버에서 세션을 관리하므로, 클라이언트가 JWT를 조작할 수 없고, 보안성이 높음.
- 유연한 관리: 서버에서 세션 만료, 갱신 등을 쉽게 관리할 수 있어, 보안 정책을 쉽게 적용할 수 있음.
- 단점
- 서버 부하: 서버가 모든 세션 정보를 유지해야 하므로, 서버의 부하가 증가할 수 있음.
- 확장성 문제: 로드 밸런싱 환경에서 세션 정보를 공유하는 것이 복잡할 수 있으며, 이를 위한 추가적인 인프라가 필요할 수 있음.
- 사용 시 고려 사항
- 세션 관리 및 데이터베이스 성능을 고려해야 하며, 필요한 경우 세션 정보를 분산된 캐시(예: Redis)에 저장하여 성능을 높일 수 있음.
728x90
반응형
'Web' 카테고리의 다른 글
HTTP 요청(Request) / 응답(Response) (0) | 2024.11.13 |
---|---|
쿠키 (Cookie) vs 세션 (Session) (0) | 2024.11.04 |