
토큰인증의 동작 방식
1. 사용자가 아이디와 비밀번호로 로그인을 시도합니다.
2. 서버 측에서는 로그인 처리 로직을 실행 한 뒤에
로그인에 성공한 경우 사용자(클라이언트)에게 유일한 토큰을 발급합니다.
3. 클라이언트는 서버 측에서 전달받은 토큰을 쿠키나 스토리지에 저장합니다.
4. 이후 서버에 요청할 때마다 해당 토큰을 HTTP 요청 헤더에 포함시켜서 전달합니다.
5. 서버는 전달받은 토큰을 검증하고 요청에 응답합니다.
토큰에는 요청한 사람의 정보가 담겨있기 때문에 서버에서는 DB조회를 하지 않고 사용자에게 맞는 응답을 할 수 있습니다.
출저:https://m.blog.naver.com/hj_kim97/222928880235
JWT는 JSON Web Token의 약자로 인증에 필요한 정보들을 Payload를 Base64Url 방식으로 인코딩하고, Signature를 통해 위변조 여부를 검증하는 JSON 형식의 토큰을 의미합니다.
JWT 기반 인증은 서버와 클라이언트 간 정보를 주고 받을 때 클라이언트의 HTTP 요청 헤더에 JSON 토큰을 넣은 후 서버는 별도의 인증 과정없이 헤더에 포함되어 있는 JWT 정보를 통해 클라이언트를 식별하는 방식입니다.
이때 사용되는 JSON 데이터는 URL-Safe 하도록 URL에 포함할 수 있는 문자만으로 만들게 되는데, JWT는 JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화하여 만듭니다. 또한 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자서명이 들어갑니다. 따라서 사용자가 JWT를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 돌려줍니다.
회원 인증: JWT 를 사용하는 가장 흔한 케이스입니다. 유저가 로그인을 하면, 서버는 유저의 정보에 기반한 토큰을 발급하여 유저에게 전달해줍니다. 그 후, 유저가 서버에 요청을 할 때 마다 토큰을 헤더에 포함하여 전달합니다. 서버가 클라이언트에게서 요청을 받을때 마다, 해당 토큰이 유효하고 인증됐는지 검증을 하고, 유저가 요청한 작업에 권한이 있는지 확인하여 작업을 처리합니다.
서버측에서는 유저의 세션을 유지 할 필요가 없습니다. 즉 유저가 로그인되어있는지 안되어있는지 신경 쓸 필요가 없고, 유저가 요청을 했을때 토큰만 확인하면 되니, 세션 관리가 필요 없어서 서버메모리는 많이 아낄수 있습니다
정보 교환: JWT는 두 개체 사이에서 안정성있게 정보를 교환하기에 좋은 방법입니다. 그 이유는, 정보가 sign 이 되어있기 때문에 정보를 보낸이가 바뀌진 않았는지, 또 정보가 도중에 조작되지는 않았는지 검증할 수 있습니다.
JWT Header는 토큰 타입과 서명 알고리즘 정보를 담는 메타데이터 영역
토큰의 타입 + 알고리즘으로 이루어져있는
사용자의 정보를 담고 있는 부분이다.
예를 들어, 사용자 ID나 이메일과 같은 정보를 포함할 수 있다.
기본적으로 인코딩된 형태로 저장된다. 서명된 값으로 보호된다.
페이로드에 포함되는 정보는 클레임 (Claims) 이라고 부른다.
토큰을 위조되지않았음을 보장한다
Header와 Payload 값을 기반으로 Secret Key를 사용해 생성한 전자서명 값이다
서버는 Signature를 검증하여 토큰이 위조되었는지 확인할 수 있다
| 구분 | 역할 | 예시 |
|---|---|---|
| Header | 토큰 형식/알고리즘 | alg, typ |
| Payload | 사용자 정보/클레임 | userId, role, exp |
| Signature | 위변조 방지 | secret key 기반 |
1)무상태(Stateless) 및 스케일링: 세션 저장소(Redis 등)가 필요 없어 서버를 자유롭게 늘릴 수 있어 분산 시스템에 적합합니다.
2)자가 수용적: 토큰에 인증에 필요한 사용자 정보가 담겨 있어, DB 조회를 최소화하여 API 성능을 높입니다.
3)보안성: 서명(Signature)을 통해 토큰이 중간에 변조되었는지 검증할 수 있습니다.간편한 정보 전달: 토큰 자체에 정보를 담아 전달하므로, 쿠키나 세션 ID 전달보다 구현이 간단하고, 모바일 앱 환경에서도 사용하기 쉽습니다.
4)범용성: JSON 기반으로 다양한 프로그래밍 언어에서 지원되며, URL Safe한 구조를 가지고 있습니다.
1) 토큰 해지불가능: 발급된 JWT는 만료 전까지 서버에서 강제로 무효화할 수 없습니다. 토큰이 탈취되면 만료될 때까지 계속 사용할 수 있어 보안 위험이 존재합니다.
2)보안 위험: JWT는 암호화하지 않고 서명만 하는 경우, 페이로드 내용을 누구나 디코딩하여 볼 수 있습니다. 민감한 정보를 담으면 안 됩니다.
2) 네트워크 부하: 모든 정보가 토큰에 포함되어 있어 세션 ID보다 훨씬 길며, 요청마다 이 토큰을 헤더에 실어 보내야 하므로 트래픽을 많이 소모합니다.
3) 무상태(Stateless)의 한계: 서버가 클라이언트 상태를 저장하지 않아 로그인 후 유저 권한이 변경되어도 토큰 만료 전까지는 이전 권한으로 통신하게 됩니다.
4) 복잡한 구현: 구현 표준이 복잡하여 개발자가 서명 알고리즘 등을 잘못 설정할 경우 심각한 보안 취약점이 발생할 수 있습니다.
| 구분 | Session | JWT |
|---|---|---|
| 저장 위치 | 서버 | 클라이언트 |
| 인증 방식 | Session ID 조회 | 토큰 검증 |
| 서버 상태 저장 | O | X |
| 확장성 | 낮음 | 높음 |
| 서버 메모리 사용 | 많음 | 적음 |