JWT란?

ZenTechie·2023년 9월 5일
0

study

목록 보기
11/11

토큰(Token) 인증이란?

토큰 인증이란,

서버가 클라이언트에게 토큰을 발급하고 발급 이후부터 모든 클라이언트는 서버에 요청을 보낼 때 요청 헤더에 토큰을 포함하여 요청을 보낸다. 서버는 클라이언트로부터 받은 토큰을 서버에서 제공한 토큰이 맞는지 검증하여 사용자 인증을 처리하고 응답하는 방식이다.

토큰은 유일하다.
토큰은 '클라이언트가 인증되었다'는 의미이다.


동작 방식


(출처: https://velopert.com/2350)

  1. 사용자(클라이언트)가 아이디/비밀번호로 로그인을 한다.
  2. 서버에서는 사용자(클라이언트)를 검증한다.
  3. 검증되었다면 서버에서는 토큰을 생성하여 해당 토큰을 응답헤더에 포함하여 클라이언트에게 전달한다.(=토큰 발급)
  4. 클라이언트는 받은 토큰을 저장하고, 서버에 요청을 할 때 마다 토큰을 HTTP 요청 헤더에 포함하여 서버에 함께 전달한다.
  5. 서버는 받은 토큰을 검증하고, 요청에 응답한다.

토큰 인증의 장/단점

장점

  • 무상태(stateless)이며 확장성이 있다. : 토큰은 클라이언트에 저장하기 때문에 stateless하다.
  • 서버를 확장, 유지보수에 유리하다.
  • 상대적으로 좋은 보안성 : 클라이언트가 서버에 요청을 보낼 때 더 이상 쿠키를 전달하지 않기 때문에 쿠키로 인해 발생하는 취약점이 사라진다.(but, 토큰 사용도 취약점이 존재할 수 있다.)
  • CORS 문제 해결

단점

  • 토큰이 탈취되면 대처가 어렵다.
  • 토큰 자체의 데이터의 길이가 길기 때문에, 인증 요청이 많아지면 네트워크 부하가 심해진다.
  • Payload 자체는 암호화가 되지 않기 때문에, 중요한 정보를 담을 수 없다.

JWT란?

JWT(Json Web Token)는 말그대로 웹에서 사용되는 JSON 형식의 토큰에 대한 표준 규격이다.
인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미한다.
(= 인증에 필요한 정보들을 Token에 담아 암호화시켜 사용하는 토큰)

주로 사용자의 인증(authentication) 또는 인가(authorization) 정보를 서버와 클라이언트 간에 안전하게 주고 받기 위해서 사용된다.

JWT는 Base64로 인코딩이 되어 있어서 육안으로 보면 eyJ로 시작하는 아주 긴 문자열이다.


JWT 구조

Header, Payload, Signature로 구성된다.

(출처: https://supertokens.com/blog/what-is-jwt)

  • Header : 토큰의 유형과 암호화 알고리즘(해시 알고리즘)의 종류를 JSON 형태로 담겨 있다.
  • Payload : 사용자의 인증/인가 정보가 담겨있다.
  • Signature: Header, Payload가 비밀키로 서명되어 담겨있다.
    • Base64 인코딩된 Header와 Base64 인코딩된 Payload 그리고 비밀키를 이용하여 암호화(=서명)한다.
    • 서버는 Signature를 통해 JWT의 무결성을 검증할 수 있다.

동작 방식

JWT 토큰은 웹에서 보통 Authorization HTTP 헤더를 Bearer <토큰>의 형태로 설정하여 클라이언트에서 서버로 전송되며, 서버에서는 토큰에 포함되어 있는 서명(signature) 정보를 통해서 위변조 여부를 빠르게 검증할 수 있다.


(출처: https://www.vaadata.com/blog/jwt-tokens-and-security-working-principles-and-use-cases/)

  1. 사용자(클라이언트)가 아이디, 비밀번호를 입력하여 서버에 로그인 인증을 요청한다.
  2. 서버는 요청을 받으면, Header, Payload, Signature를 정의한다. Hedaer, PayLoad, Signature를 각각 Base64로 한 번 더 암호화하여 JWT를 생성하고 이를 쿠키에 담아 클라이언트에게 발급한다.
  3. 클라이언트는 서버로부터 받은 JWT를 저장한다. 이후 서버에 요청을 보낼 때, Authorization Header에 JWT를 Bearer <토큰>의 형태로 설정하여 요청을 보낸다.
  4. 서버는 클라이언트가 보낸 JWT가 서버에서 발행한 것이 맞는지 확인한다.
  5. 서버에서 발행한 JWT가 맞다면, 인증을 통과시킨다.

장/단점

장점

  • 서버 입장에서는 토큰만 검증하면 되므로 확장성이 용이하다.
  • 인증을 위한 별도의 저장소가 필요 없다
  • Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있다.
  • 쿠키를 사용하지 않으므로, CORS 문제를 해결할 수 있다.

단점

  • 토큰의 길이가 늘어날수록 네트워크 부하가 늘어난다.
  • 특정 토큰을 강제로 만료시키기 어렵다. 즉, 이미 발행된 토큰에 대해 서버는 아무런 제어도 할 수 없다.

발행된 토큰 악용을 막기 위해서..

이미 발행된 토큰에 대한 악용을 막기 위해서 Access TokenRefresh Token을 함께 사용한다.
Access Token만 사용한다면 이를 탈취당했을 때 문제가 생긴다. 토큰이 만료되기 전 까지, 이를 부당하게 획득한 사람이 마음대로 정보에 접근 가능하기 때문이다. 이는 토큰에 유효기간을 부여함으로서 대응할 수 있다.

그렇다면 유효기간을 어떻게 설정해야 할까? 유효기간이 너무 짧다면, 사용자는 Token을 계속해서 새롭게 발급받아야 하는 불편함을 겪는다. 그렇다고 너무 길게 설정하면, 탈취당했을 때 취약해진다.

이에 대응하기 위한 것이 Refresh Token이다.

클라이언트가 아이디와 패스워드로 로그인 요청을 하는 상황을 살펴보자.

서버는 로그인을 성공시키면서 클라이언트에게 Access Token과 Refresh Token을 동시에 발급한다.
이 Refresh Token은 긴 유효기간을 가지면서, Access Token이 만료됐을 때 새로 재발급을 받을 수 있게 해준다.
만약, Access Token 이 만료되면, 클라이언트는 같이 발급된 Refresh Token 을 이용하여 서버에 Access Token 재발급을 요청한다.

Access Token, Refresh Token은 모두 JWT 이다.

Access Token: 접근
Refresh Token: 재발급

Access Token의 유효기간은 5분, 1시간, 24시간 등 다양하지만, 1일을 넘지 않는게 일반적이다.
Refresh Token 은 약 2주.

결론

  • JWT서명(인증)이 목적이다. 즉, 진짜 목적은 정보 보호가 아닌, 위조 방지이다.
  • 서명이 되어 있는 JWT는 서버에서만 유효성을 검증할 수 있지만, 그 안에 저장된 데이터는 누구나 쉽게 열람이 가능하다. 따라서, 민감한 정보는 JWT 토큰에 그대로 저장하지 않아야 한다.

참고 & 출처

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-JWTjson-web-token-%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC#token_%EC%9D%B8%EC%A6%9D

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-Access-Token-Refresh-Token-%EC%9B%90%EB%A6%AC-feat-JWT

https://www.daleseo.com/jwt/

https://velopert.com/2350

https://hudi.blog/self-made-jwt/

profile
데브코스 진행 중.. ~ 2024.03

0개의 댓글