JWT토큰이란?

CinnamonTree·2022년 2월 4일
1

네트워크

목록 보기
1/7

JWT: JSON Web Token 으로 전자서명된 URL-safe(URL로 이용할 수있는 문자로만 구성된) JSON이다.

Authentication vs Authorization

Authentication 인증: 사용자가 계정을 사용하려고 할때 로그인을 통해 인증을 받는다.
Authorization 인가: 로그인이 유지되는 상태에서 클라이언트가 하고자 하는 작업이 해당 클라이언트에게 허가된 작업인지를 확인한다.

로그인에 대해서...

로그인은 무거운 작업이다. 데이터베이스에 저장된 사용자 계정의 해시값등을 꺼내온 다음 사용자가 입력한 암호를 서버에 내장된 복잡한 알고리즘을 통해 계산한 값과 일치되는지 확인하는 과정을 거쳐야 하기 때문이다.

보통 세션 또는 JWT토큰을 사용하는 방식으로 이루어진다.

웹 토큰 방식(ex. JWT 토큰)

사용자가 로그인을 하게 되면 토큰이라는 표를 출력해서 건너줌. 세션과는 달리 서버가 기억하고 있지 않다는 뜻.

JWT토큰의 구조는 인코딩 또는 암호화된 세가지 데이터를 이어붙인 형식이다.
각각 1.header, 2.payload, 3.verify signature(서명)으로 구분된다.

payload 를 base64로 디코딩을 해 보면 JSON형식으로 여러 정보들이 들어있는 것을 확인할 수 있다. 이 토큰을 누가 누구에게 발급했는지, 토큰이 언제까지 유효한지, 서비스가 사용자에게 이 토큰을 통해 공개하기 원하는 내용(서비스 레벨, 관리자 여부) 등을 담을 수 있다. 이러한 토큰에 담긴 데이터를 Claim이라고 한다.

Payload는 조작이 가능한가?

base64로 디코딩 될 수 있다는 점에서 사용자가 payload를 조작해서 악용할 수 있다는 의문이 생길 것이다.

1번 header에는 type이 JWT로 들어간다. 다른 하나는 alg가 들어간다. alg에는 3번 서명값을 만드는 알고리즘이 들어간다. HMAC, SHA256 또는 RSA와 같은 여러 암호화 방식 중 하나를 지정 할 수 있다. [header, payload, 서버에 숨겨놓은 비밀 값]을 암호화 알고리즘에 넣고 돌리면 서명값이 만들어지는데, 서버는 클라이언트로부터 받은 header와 payload를 가지고 서버 자신에게 내장된 비밀값을 포함하여 서명값을 만들어 보고, 일치하면 허용하는 방식으로 동작한다. 암호화는 단방향 알고리즘이기 때문에 비밀값을 역방향으로는 찾지 못한다.

따라서 2번 payload를 조작해서 보낸다 하더라도, 서버에 숨겨놓은 비밀값을 알지 못하면 허용이 되지 않는 것이다.

JWT의 장단점

최종적으로 JWT의 장점은 서버가 사용자들의 상태를 따로 저장해서 관리할 필요 없이 비밀값만 가지고 사용자들의 요청이 들어올 때 마다 계산하여 확인할 수 있는 것이다. 이렇게 시간에 따라 바뀌는 상태값을 갖지 않는 것을 stateless하다고 한다. (세션은 stateful)

그렇다고 JWT가 만능인가?

세션처럼 모든 사용자들의 상태를 기억하고 있다는 것은 구현하기 부담스럽고 고려사항이 많지만, 기억하는 대상의 상태를 언제든지 제어할 수 있다는 장점이 있다. 예를들어 핸드폰으로 로그인한 사용자가 PC에서 로그인하면 핸드폰에서 로그아웃되도록 조정할 수 있다.

결국 서버가 가지고 있지 않아서 편하기는 하지만, 통제가 되지 않아 불편하다는 점이 있다. 심각한 경우 토큰이 악당에게 탈취당할 경우, 악당이 가져간 토큰을 무효화할 방법이 없다.

따라서 실서비스로 JWT만으로 구현하는 경우는 별로 없다.

JWT토큰 단점의 해결방안

위의 단점들을 보완하기 위해 나온 해결방법이 있다.
바로 만료시간을 가깝게 잡아 토큰의 수명을 짧게 주는 것!

먼저 로그인을 하면 토큰을 2개 준다.
수명이 몇 시간 또는 몇 분으로 짧은 access토큰과 수명이 길게 잡힌(몇주) refresh토큰이다. access토큰과 refresh토큰을 발급하고 클라이언트에게 보내고 나서 refresh토큰값을 데이터베이스에도 저장한다. 클라이언트는 access토큰의 수명값이 다하면 refresh토큰을 보낸다. 서버는 db에 저장된 refresh토큰값과 대조한 후 일치하면 새로운 access토큰값을 보내준다. 따라서 중간에 access토큰이 탈취당하여도 오래 쓰지는 못한다. db에 refresh토큰을 지워버리면은 access토큰이 만료되고 재발급받지 못할것이다.

결론

JWT에도 한계점이 존재한다. 구현하기 편리하지만 자신의 서비스에 적합한지 충분히 고려해야 한다.

0개의 댓글