들어가기 앞서..
JWT를 공부하기 전, 우선으로 Session 인증 방식과 Token 인증 방식에 대해 알아둘필요가 있다.
[개념] Session 기반 인증 vs Token 기반 인증
[개념] Session 기반 인증 vs Token 기반 인증
인증 방식 종류 JWT에 대해 공부하기 전, 우선적으로 인증 방식 종류에 대해 알아보겠다. 크게 2가지 인증 방식이 있다. Session 기반 인증 Token 기반 인증 2가지 방식의 차이는 '인증 확인 증거를 어
soohykeee.tistory.com
JWT란?
JWT는 JSON Web Token으로, 인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미한다.
JWT 구성요소
JWT는 header, payload, signature로 나눠져 있다.
* 헤더 (Header)
- 어떠한 알고리즘으로 암호화 할것인지, 어떠한 토큰을 사용할 것인지에 대한 정보가 저장되어있다.
- "alg" : Signature 해싱 알고리즘을 지정한다. 해싱 알고리즘으로는 보통 'HMAC-SHA256', 'RSA'가 사용되며, 이 알고리즘은 토큰을 검증할 때 사용되는 Signature 부분에서 사용된다.
- "typ" : 토큰의 타입을 지정한다. JWT를 의미
* 정보 (Payload)
- 전달하려는 정보가 들어있다. 여기에 담는 정보의 한 '조각'을 클레임 (Claim)이라고 부르고, 이는 JSON 형태로 Key-Value 의 쌍으로 이루어져있다.
- Payload에 있는 내용은 수정이 가능하며, 더 많은 정보를 추가할수도 있다. 하지만 노출과 수정이 가능하기에 인증에 필요한 최소한의 정보, 즉 민감한 개인정보가 아닌 정보들이 저장되어 있어야 한다.
- 클레임 (Claim)
- 클레임은 크게 3가지 분류로 나뉜다.등록된(registered) 클레임, 공개(public) 클레임, 비공개(private) 클레임
- 등록된 클레임 (Registered Claim) : 등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기위하여 이름이 이미 정해진 클레임들이다. 등록된 클레임의 사용은 선택적이며, 다음과 같다.
- iss : 토큰 발급자
- sub : 토큰 제목
- aud : 토큰 대상자
- exp : 토큰의 만료시간
- nbf : Not Before을 의미하며, 토큰의 활성날짜
- iat : 토큰이 발급된 시간
- jti : JWT의 고유 식별자
- 공개 클레임 (Public Claim) : 공개 클레임들은 충돌이 방지된 이름을 가지고 있어야 한다. 이를 위해서는 클레임 이름을 URL 형식으로 짓는다.
ex ) { "http://jangsoohyuck.com/jwt_claims/admin": true } - 비공개 클레임 (Private Claim) : 클라이언트와 서버간의 협의하에 사용되는 클레임 이름들이다. 공개 클레임과 달리 이름이 중복되어 충돌이 될 수 있으니 사용시 유의해야한다.
ex ) { "username" : "soohyuck" }
* 서명 (Signature)
- 가장 중요한 부분으로, Header와 Payload를 합친 후 발급해준 서버가 지정한 Secret Key로 암호화 시켜 Token을 변조하기 어렵게 만들어주는 부분이다.
- 예를 들어, Token이 발급된 후 누군가 Payload의 정보를 수정한다면 Payload에는 수정된 정보가 저장되어 있겠지만, Signature에는 수정되기 전 Payload 내용을 기반으로 암호화된 정보가 저장되어 있기 때문에 이를 이용하여 서버는 Token이 조작되었는지 확인할 수 있다.
JWT의 동작 원리
- 사용자가 Id, Password를 입력하여 로그인을 요청
- 서버는 회원 DB에 저장되어 있는 사용자인지 확인
- 확인이 되면 서버는 로그인 요청 확인 후, Secret Key를 통해 Token 을 발급
- Token을 클라이언트에게 전달
- 서비스 요청과 권한을 확인하기 위해 헤더에 데이터 (JWT) 요청
- 데이터를 확인하고 JWT에서 사용자 정보를 확인
- 클라이언트 요청에 대한 응답과 요청한 데이터를 전달
위처럼 Token 기반 인증 방식은 사용자의 인증이 완료된 이후에 Token을 발급해주고, Token을 전달받은 클라이언트는 Token을 저장해두고 서버에 요청을 할 때마다, 해당 Token을 같이 전달한다. 서버는 클라이언트의 요청이 올때마다 전달해준 Token을 검증하고 응답하는 방식으로 작동한다.
JWT 장단점
장점
- 무상태 (Stateless), 확장성이 있다. 기존 서버에 세션을 저장하는 방식에서 서버 여러대를 사용하여 요청을 분산하였다면, 어떤 유저가 로그인했을 때 그 유저는 처음 로그인한 서버에만 요청을 내보내도록 설정을 추가로 해줘야한다. 하지만 토큰을 사용한다면 토큰 값만 알고 있다면 어떤 서버로 요청이 들어가던 상관이 없다. 즉, 세션 스토리지가 필요없게된다.
- 보안성 쿠키를 전달하지 않아도 되므로 쿠키를 사용함으로써 발생하는 취약점이 사라진다.
- 여러 플랫폼 및 도메인 어플리케이션 규모가 커지면 여러 디바이스를 호환 시키고 더 많은 종류의 서비스를 제공한다. 토큰을 사용한다면 그 어떤 디바이스에서도 그 어떤 도메인에서도 토큰만 유효하다면 요청이 정상적으로 처리된다.
단점
- 길이 Claim에 넣는 데이터가 많아질수록 JWT 토큰이 길어진다. API 호출마다 토큰 데이터를 서버에 전달해야하는데 길이가 길어지게 되면, 네트워크 대역폭 낭비가 심하게 발생할 수 있다.
- 보안 JWT는 기본적으로 Payload에 대한 정보를 암호화하지 않는다. 단순히 'BASE64'로 인코딩만 하기에 중간에 패킷을 가로채거나 기타 다른 방법으로 토큰을 취득했으면 디코딩을 통해 데이터를 확인할 수 있다. 그렇기에 JWE를 통해 암호화하거나 중요 데이터를 Payload에 넣어서는 안된다.
참고:
https://velog.io/@hahan/JWT%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80
https://velog.io/@dnjscksdn98/JWT-JSON-Web-Token-%EC%86%8C%EA%B0%9C-%EB%B0%8F-%EA%B5%AC%EC%A1%B0
https://etloveguitar.tistory.com/101
https://tech.toktokhan.dev/2021/04/30/JWT/