[6.23 TIL] JWT(JSON Web Token)

Jihun·2022년 6월 23일
0

TIL

목록 보기
5/6

JWT 토큰을 배우기 앞서 서버 기반 인증에 대한 개념이 있으면 토큰이 왜 사용되는지 이해하는 데 도움이 된다.

기존의 인증 시스템은 서버 기반의 인증 방식으로, 서버 측에서 사용자들의 정보를 기억하고 있어야 한다. 사용자들의 정보를 기억하기 위해서는 세션을 유지해야 하는데, 메모리나 디스크 또는 데이터베이스 등을 통해 관리한다.

  1. 유저가 로그인하면 세션이 서버 메모리(혹은 데이터베이스) 상에 저장된다. 이때, 세션을 식별하기 위한 Session Id를 기준으로 정보를 저장한다.
  2. 브라우저에 쿠키로 Session Id가 저장된다.
  3. 쿠키에 정보가 담겨있기 때문에 브라우저는 해당 사이트에 대한 모든 Request에 Session Id를 쿠키에 담아 전송한다.
  4. 서버는 클라이언트가 보낸 Session Id 와 서버 메모리로 관리하고 있는 Session Id를 비교하여 인증을 수행한다.

문제점

세션

세션사용자가 인증을 할 때, 서버는 이러한 정보를 저장해야 하고 이를 세션(Session)이라고 부른다. 대부분의 경우에는 메모리에 저장하는데, 로그인 중인 사용자가 늘어날 경우에는 서버의 RAM에 부하가 걸리게 된다. 이를 피하기 위해 데이터베이스에 저장을 하기도 하는데, 이러한 방식 역시 데이터베이스에 무리를 줄 수 있다.

확장성

확장성사용자가 늘어나게 되면 더 많은 트래픽을 처리하기 위해 여러 프로세스를 돌리거나 컴퓨터를 추가하는 등 서버를 확장해야 한다. 세션을 사용한다면 세션을 분산시키는 시스템을 설계해야 하지만 이러한 과정은 매우 어렵고 복잡한다.

CORS

CORS(Cross-Origin Resource Sharing)웹 어플리케이션에서 세션을 관리할 때 자주 사용되는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 있다. 따라서 쿠키를 여러 도메인에서 관리하는 것은 번거롭다.

토큰 기반 인증 시스템

세션을 사용하는 서버 기반 인증 시스템과 달리,
클라이언트가 서버에 접속하면 서버에서 해당 클라이언트에게 인증되었다는 의미로 토큰을 부여한다.
이 토큰은 유일하며 토큰을 발급받은 클라이언트는 또 다시 서버에 요청을 보낼 때 요청 헤더에 토큰을 심어서 보낸다.
그럼 서버에서는 클라이언트로부터 받은 토큰을 서버에서 제공한 토큰과의 일치 여부를 체크하여 인증 과정을 처리하게 된다.

서버가 인코딩한 정보를 클라이언트에게 던져주고 나면 이를 저장할 필요가 없다.

  1. 사용자가 아이디와 비밀번호로 로그인을 한다.
  2. 서버 측에서 해당 정보를 검증한다.
  3. 정보가 정확하다면 서버 측에서 사용자에게 사용자를 위한 유일한 토큰을 발급한다.
  4. 클라이언트 측에서 전달받은 토큰을 저장해 두고, 서버에 요청을 할 때마다 해당 토큰을 서버에 함께 전달한다. 이때 Http 요청 헤더에 토큰을 포함시킨다.
  5. 서버는 토큰을 검증하고, 요청에 응답한다. 토큰에는 요청한 사람의 정보가 담겨있기에 서버는 DB를 조회하지 않고 누가 요청하는지 알 수 있다.

이점

무상태(stateless)이며 확장성(scalability)

토큰은 클라이언트 사이드에서 저장하기 때문에 완전히 stateless하다 그렇기에 서버를 확장하기에 매우 적합한 환경을 제공한다

보안성

클라이언트가 서버로 요청을 보낼 때 더 이상 쿠키를 전달하지 않으므로, 쿠키 사용에 의한 취약점이 사라지게 된다. 하지만 토큰 환경의 취약점이 존재할 수 있으므로 이에 대비해야 한다.

확장성(Extensibility)

Extensibility 는 로그인 정보가 사용되는 분야를 확장하는것을 의미. 토큰을 사용하여 다른 서비스에서도 권한을 공유 할 수 있다.

토큰 기반의 인증 시스템에서는 토큰에 선택적인 권한만 부여하여 Facebook, Google 등과 같은 소셜 계정을 이용하여 다른 웹서비스에서도 로그인을 할 수 있다.

여러 플랫폼 및 도메인

어플리케이션과 서비스의 규모가 커지면 우리는 여러 디바이스를 호환 시키고, 더 많은 종류의 서비스를 제공하게 되는데 토큰을 사용한다면, 그 어떤 디바이스, 도메인에서도 토큰만 유효하다면 요청이 정상적으러 처리된다.


JWT(JSON Web Token)란?

JWT란 인증에 필요한 정보들을 암호화시킨 토큰을 의미한다

JWT기반 인증은 JWT토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식이다.

JWT는 .을 구분자로 나누어지는 세 가지 문자열의 조합이다.
.을 기준으로 좌측부터 HeaderPayloadSignature를 의미한다.

알고리즘 형식 (RSA / SHA256 등)

  • alg : 서명 암호화 알고리즘(ex: HMAC SHA256, RSA)
  • typ : 토큰 유형

Payload

토큰에서 사용할 정보의 조각들인 Claim 이 담겨있다. (실제 JWT 를 통해서 알 수 있는 데이터)
즉, 서버와 클라이언트가 주고받는 시스템에서 실제로 사용될 정보에 대한 내용을 담고 있음.

Registed claims : 미리 정의된 클레임.

  • iss(issuer; 발행자), exp(expireation time; 만료 시간), sub(subject; 제목), iat(issued At; 발행 시간), jti(JWI ID) 등이 있다.

Public claims

사용자가 정의할 수 있는 클레임 공개용 정보 전달을 위해 사용.

Private claims

해당하는 당사자들 간에 정보를 공유하기 위해 만들어진 사용자 지정 클레임. 외부에 공개되도 상관없지만 해당 유저를 특정할 수 있는 정보들을 담는다

Signature

헤더의 인코딩 값과 정보의 인코딩 값을 합친 후 비밀키로 해쉬를 하여 생성함.
시그니처에서 사용하는 알고리즘은 헤더에서 정의한 알고리즘 방식을 활용한다.
시그니처의 구조는 (헤더 + 페이로드)와 서버가 갖고 있는 유일한 key값을 합친 것을 헤더에서 정의한 알고리즘으로 암호화를 한다.

Header와 Payload는 단순히 인코딩된 값이기 때문에 제 3자가 복호화 및 조작할 수 있지만,Signature는 서버 측에서 관리하는 비밀키가 유출되지 않는 이상 복호화할 수 없다.따라서 Signature는 토큰의 위변조 여부를 확인하는데 사용된다.

JWT를 이용한 인증 과정


1. 사용자가 ID, PW를 입력하여 서버에 로그인 인증을 요청한다.
2. 서버에서 클라이언트로부터 인증 요청을 받으면, Header, PayLoad, Signature를 정의한다.Hedaer, PayLoad, Signature를 각각 Base64로 한 번 더 암호화하여 JWT를 생성하고 이를 쿠키에 담아 클라이언트에게 발급한다.
3. 클라이언트는 서버로부터 받은 JWT를 로컬 스토리지에 저장한다. (다른 곳에 저장할 수도 있음)API를 서버에 요청할때 Authorization header에 Access Token을 담아서 보낸다.
4. 서버가 할 일은 클라이언트가 Header에 담아서 보낸 JWT가 내 서버에서 발행한 토큰인지 일치 여부를 확인하여 일치한다면 인증을 통과시켜주고 아니라면 통과시키지 않으면 된다.인증이 통과되었으므로 페이로드에 들어있는 유저의 정보들을 select해서 클라이언트에 돌려준다.
5. 클라이언트가 서버에 요청을 했는데, 만일 액세스 토큰의 시간이 만료되면 클라이언트는 리프래시 토큰을 이용해서
6. 서버로부터 새로운 엑세스 토큰을 발급 받는다.

서버에서 가장 피해야 할 것은 데이터베이스 조회이다.서버 자체가 죽는 경우도 있지만, 대부분 DB가 터져서 서버도 같이 죽는 경우가 허다하기 때문이다.

이런 점에서, JWT 토큰은 DB조회를 안해도 되는 장점을 가지고 있다는 점이다.만일 payload에 유저이름과 유저등급 을 같이 두고 보내면, 서버에서는 유저이름을 가지고 DB를 조회해서 유저 등급을 얻지않아도 바로 원하는 정보를 취할수 있다.

JWT 단점

  1. 쿠키/세션과 다르게 JWT는 토큰의 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해진다.
  2. Payload 자체는 암호화되지 않기 때문에 유저의 중요한 정보는 담을 수 없다.
  3. 토큰을 탈취당하면 대처하기 어렵다.

    데이터베이스 조회를 안하게되서,데이터베이스 쪽에서는 성능적인 이득을 얻을 수 있는데, 네트워크 쪽에서는 패킷이 많이 전달 되기 때문에 성능이 저하 될 수 있다.

Reference

profile
slow and steady

0개의 댓글