이번 포스팅에서는 JWT token이 무엇인지, 어떠한 방식으로 작동하는지에 대하여 짚어보는 시간이 되겠습니다.
토큰 인증 방식
우선, JWT Token을 이해하기 전, Session기반 인증 방식과, 토큰 인증 방식을 이해하여야 합니다.
Session기반 인증방식
서버의 세션을 사용하여 인증을 하는 방식으로, 서버측(서버 메모리(RAM)이나 데이터베이스)에서 사용자의 인증정보를 관리 및 처리하는 인증 방식을 말합니다. 이에따라 클라이언트가 요청할 때 마다 해당 요청자의 SessionID값을 스토리지에서 탐색하는데 오버헤드가 발생하여 사용자가 증가하면 할수록 성능저하 문제를 일으킬 수 있습니다.
Token기반 인증 방식
이러한 Session기반의 인증방식의 단점을 개선하기위하여 Token기반 인증방식이 만들어졌습니다.
인증받은 사용자에게 토큰을 발행하고, 로그인이 필요한 요청의경우에 해당 유저의 정보에관한 내용이 담긴 토큰을 같이 담아 보내기때문에 Session기반 인증방식에 비해 사용자 탐색을 위한 오버헤드가 발생하지 않으며, Session기반 인증방식에 비해 사용자의 상태를 유지하지않는다는점에서 Stateless하다는 특징이 있습니다.
JWT Token?
이하 Json Web Token으로 불리우는 Jwt Token은 '당사자 간 정보를 JSON 개체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준'으로 정의되어있습니다.
이러한 JWT Token은 private key, public/personal key 쌍을 사용하여 서명할 수 있습니다.
JWT token은 인증에 필요한 정보들을 Base64 URL-safe encode를 통해 인코딩하여 직렬화하였으며, 내부에는 위변조 방지를 위하여 개인키를 통한 전자서명도 함께 들어있습니다.
따라서 사용자가 JWT토큰을 서버로 보내면, 서버는 서명을 검증하는 방식을 통해 해당 토큰이 위/변조되었는지, 유효한 토큰인지를 판별하게됩니다.
JWT Token 내부
JWT token은 크게 Header, Payload, Signature 세 파트로 나뉘며, 각각의 파트는 아래와 같이 ' . '로 분리됩니다.
각각의 파트를 살펴보겠습니다.
Header
1. 어떠한 토큰 종류인지
2. 어떠한 암호화 알고리즘이 사용되었는지 (예를들면, HMAC SHA256 or RSA.)
{
"alg": "HS256",
"typ": "JWT"
}
<For Example of Header>
Payload
토큰에서 사용될 정보의 조각들인 클레임들을 포함하는 Payload입니다.
이는 크게 Registerd claims, public claims, private claims 세 가지로 나뉩니다.
- Registerd claims (미리 정의된 클레임)
- iss (issuer : 발행자)
- exp (expiration time : 만료 시각)
- sub (subject : 제목)
- iat (issued At : 발행 시각)
- jti (jwt Id : JWT 아이디)
- aud (audience : Jwt 수신자)
- nbf (not before : 언제까지 프로세싱되면 안되는 특정 시각)
- public claims : 사용자가 정의할 수 있는 클레임. 정보 전달을위해 사용합니다.
- private claims : 해당되는 당사자들 간 정보를 공유하기 위해 만들어진 사용자 지정 클레임으로, 외부에 공개되도 상관없으나, 유저를 특정할 수 있는 정보가 담겨있습니다.
예를들어, Payload는 이러한 형태입니다.
{
"jti" : "5123", // registerd claims
"exp" : "2131500000", // registerd claims
"https://day-kraken.tistory.com" : true, // public claims
"username" : "pepedog" // private claims
}
SIGNATURE
인코딩된 헤더, 인코딩된 페이로드, Secret key(비밀 키), 헤더에 적시된 암호화 알고리즘을 통해 서명이 되는 부분입니다.
예를들어,
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
의 구조를 띄며, base64 Encode된 header와 payload사이에 "."을 넣고, 서버의 개별적 secret key를 넣고 헤더에 적시된 암호화기법을 사용하여 암호화 합니다.
이를 통해 Jwt token을 누군가 탈취하여 위변조 후 서버로 보낸다 하여도, 위변조된 토큰의 SIGNATURE은 기존의 인증된 JWT토큰의 SIGNATURE와 일치하지않으므로 서명이 되지않음으로 보안성을 챙길 수 있게됩니다. (내부동작은 'Hash'를 참고하면 될것같습니다.)
JWT Decode
이 Jwt token은 아래와같은 무의미한 값들이 합쳐진형태를 띄게되는데, 이 값들 자체가 보안성이 뛰어난것은 아닙니다. 이러한 값들은 누구나 쉽게 디코딩을 할 수 있습니다.
직접 Jwt token을 인코딩(생성) 혹은 디코딩(복호화) 해보는 방법은 아래 URL에서 쉽게 진행이 가능합니다.
JWT.IO
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
jwt.io
동작 과정
일반적으로 Jwt token은 Bearer 스키마를 사용하는 Authorization 헤더에 보냅니다.
Jwt token을 활용한 인증방식의 동작과정은 이러합니다.
- 응용 프로그램 또는 클라이언트는 인증 서버에게 인증을 요청합니다.
- 인증이 허가되면, 인증 서버는 응용 프로그램에 액세스 토큰을 반환합니다.
- 응용프로그램은 액세스 토큰을 사용(Header에 담아서)하여 보호된 자원(ex : API)에 접근을 합니다.
*중요한 점은, JWT는 서명(인증)이 목적입니다.
기본적인 Jwt token방식의 구현은 토큰의 탈취에 대한 가능성을 온전히 프로토콜의 보안성에 맡기고 진행하기때문에, 통신과정에서의 보안성이 강점이 아닌, 위조 방지에 의의가 있습니다. 이러한 이유로 토큰의 payload에는 사용자의 비밀번호와 같은 민감한 정보는 넣지않습니다.
위에서 말씀드렸듯이, signature에 사용된 서버의 비밀키가 노출되지않는 한은 데이터를 위조하여도 Signature부분에서 바로 걸러지기때문에 서명의 보안성에 특화된 인증방식이라고 보시면 될것같습니다.
JWT토큰의 장단점
장점
- 인증정보에 대한 서버측의 별도의 저장소를 가지고있지않아도 됩니다. => 이는 별도의 탐색/조회에 발생되는 리소스를 줄일 수 있다는 뜻으로, 서버에 부담을 덜 수 있습니다. 예를 들자면, payload에 user ID를 넣는다면 별도의 db조회 혹은 메모리 조회를 탐색할 필요가 없어지므로, 탐색 후 해당 유저를 찾아내어 추가적인 로직을 처리하는 session방식에 비해 성능적인 효과를 누릴 수 있습니다.
- Signature를 통해 데이터의 위/변조를 막을 수 있습니다.
- 서버는 Stateless하므로 서버의 확장성에 대하여 session방식보다 이점을 가져갈 수 있습니다.
단점
- 토큰 자체에 정보를 담고있으므로 이 정보에 대한 탈취에 대해서는 무방비합니다.
- 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있습니다. (JWT 공식사이트에 따르면, 몇몇 서버는 8KB이상의 헤더를 받아낼 수 없다고 합니다.)
- stateless, 즉 클라이언트측에서 토큰에관한 정보를 보유하고있으므로, 탈취당할 시 대처하기가 어렵습니다. (session방식에서는 session을 즉시 종료시키면 되지만, cookie의 경우 즉시 종료시킬 수 없습니다. 하지만, access token의 expire time을 짧게 가져가는 방법으로 어느정도 이점을 가져갈 수 있으며, 추가적인 보안적 구현을 통해 비정상적 토큰 요청이 확인되면 black list에 token을 넣어 관리를 한다던지 하는 처리를 할 수 있습니다.)
후기
Jwt가 Session방식의 한계에 따라 개선하고자 나온 인증방식은 맞지만, 개인적으로 Session방식보다 무조건적으로 좋다고는 생각하지않습니다.
세션로그인 포스팅때도 이야기했지만, 무엇이 무조건적으로 더 좋아서 사용한다기보다는, 각각의 방식이 어떠한 장/단점을 갖고있고, 서비스의 특성상 어느방식이 유리할지에따라 적재적소에 사용하는것이 좋은 결과를 가져올것이라고 생각하며, 이번 포스팅을 마치겠습니다.
혹여, 잘못된 정보가 있거나, 본인의 생각을 말씀해주시고싶다면 댓글로 남겨주시면 좋겠습니다.
긴 글 읽어주셔서 감사합니다.
출처
🌐 JWT 토큰 인증 이란? (쿠키 vs 세션 vs 토큰)
Cookie / Session / Token 인증 방식 종류 보통 서버가 클라이언트 인증을 확인하는 방식은 대표적으로 쿠키, 세션, 토큰 3가지 방식이 있다. JWT를 배우기 앞서 우선 쿠키와 세션의 통신 방식을 복습해
inpa.tistory.com
JWT.IO
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
jwt.io
'Programming > Development' 카테고리의 다른 글
[ Message Broker ] Kafka, RabbitMQ, Redis(Pub/Sub) (1) | 2024.09.05 |
---|---|
[SpringBoot] 외부 오픈API Websocket서버 네트워크 연결 장애 문제 해결 [업비트 Websocket API] (0) | 2024.08.26 |
[Session] Session 개념 정리 (1) | 2024.06.20 |