본문 바로가기

Development Log

[Development Log] JWT...왜 써야 하는데?

JWT... 분명 프로젝트에서 기본적으로 많이 사용했고, 과제들에서 요구사항들도 필수 요구사항이라고 할 수 있을 정도로 실무에서 JWT를 많이 사용하고 있다는 것을 알 수 있었다. 이 글을 쓰는 이유는 아래 블로그를 작성했던 것처럼 JWT에 대해서 왜 써야 하고 어디에 저장을 해야 하고 어떻게 개발을 해야 하는지에 대하여 고민했던 시절이 있었다.

 

https://dego.tistory.com/22

 

[React/NestJS/TypeScript] 로그인 시 JWT Token 발급 및 인증(Token sessionStorage 저장)

일단 만들고 나중에 정리하자.. 고 했지만 결국 정리가 되지 않다 보니까 흐름을 이해하지 못하는 것 같아서 정리하면서 마무리를 해보려고 한다. 회사 다닐 때는 이미 로그인, 회원가입은 전부

dego.tistory.com

 

하지만, 면접에서 근본적인 질문이었던 JWT 왜 사용하는가? 에 대한 질문 의도에 맞는 답변을 하지 못했다. JWT에 대한 질문과 내가 그걸 왜 썼는지에 대해서 예전에 블로그로 기록을 해두었지만 시간이 흐르면서 머릿속에서는 사라져버렸다. 그렇기 때문에 JWT가 무엇인지에 대한 답변으로 이어졌고 당연히 면접관님께서 원하시던 방향의 대답이 아니었다. 여기서 머릿속이 하얘졌다. 

 

이전 JWT 정리한 블로그 내용 중 일부 내용

 

위에 정리한 것처럼 토큰 안에 필요한 정보들이 간결하게 들어가 있고 인증 정보에 대한 별도의 저장소가 필요 없다는 것!!! 왜 이걸 암호화로 생각하고 답변했는지 진짜 스스로한테 의문이었다. 면접관님의 답변으로 이건 암호화가 아니라는 것을 알려줘야 할 것 같아서 암호화 개념이 아니다고까지 얘기가 나와버렸다.. 😅

 

그래서 이 기회에 JWT를 써야 하는 이유와 JWT에 대한 기본적인 것들을 정리해두려고 한다. 사실 실전으로 JWT를 왜 써야 하는가를 느끼고 싶지만 아직까지 그런 경험이 없기 때문에 스스로의 정답을 찾아가 보려고 한다. 두 번 다시 대답을 못하는 상황을 만들고 싶지 않다..

 

그래서 인증 방법이 뭐가 있는데?

웹에서는 HTTP 방식을 통해서 데이터를 주고받는 방식은 state-less를 지향한다. 즉, 클라이언트와 서버와의 요청/응답은 독립적으로 서로의 상태를 알 수 없기 때문에 로그인 한 이후에 다른 페이지로 넘어간다 해도 다시 로그인을 하여 인증해야 한다. 생각만 해도 번거롭고 사용자의 입장으로 본다면 다시는 접속하고 싶지 않을 사이트로 기억이 될 것 같다.

 

그렇기 때문에 state-less 상태가 아닌 state-ful 상태로 유지할 수 있는 방법이 Cookie, Session, Token 방식이라고 한다. Token을 얘기하기 전에 Cookie와 Session에 대해서도 간단하게 미리 파악하고 가자!

 

1. Cookie 인증

클라이언트가 서버에 요청 ➡️ 서버는 클라이언트에 저장하고 싶은 정보를 응답 헤더 Set-Cookie에 저장 ➡️ 클라이언트는 요청 보낼 때 서버에서 저장한 쿠키를 요청 헤더의 Cookie에 저장하여 호출 ➡️ 서버는 Cookie에 담긴 정보로 인증

 

위의 순서대로 Cookie에 저장하여 사용할 수 있지만, 요청할 때 쿠키의 값을 그대로 보내기 때문에 보안에 취약하고 용량 제한이 있기 때문에 많은 정보는 담을 수 없다. 또한, 쿠키는 웹브라우저가 관리하기 때문에 크롬, 엣지, 파이어폭스 등 여러 종류의 브라우저들에서 동일한 내용을 저장해도 쿠키들은 브라우저에 종속되어 있기 때문에 브라우저간 공유가 불가능하다고 하다.

 

2. Session 인증

클라이언트가 서버에 요청(로그인) ➡️ 서버는 Session에 저장되는데 Cookie에 Session ID 기준으로 저장 ➡️ 클라이언트의 요청에 Session ID를 Cookie에 저장하여 호출 ➡️ 서버는 클라이언트가 보낸 Session ID를 서버 메모리로 관리하고 있는 Session ID와 비교하여 인증

 

Cookie 인증에서는 정보들을 Cookie 에 그대로 저장하여 외부 노출에 위험을 겪는다면 Session의 경우 Session ID만을 Cookie에 저장하기 때문에 외부에 노출되어도 개인적인 정보들이 노출되지 않는다. 하지만, 사용자의 수가 증가할수록 서버에 부하가 많이 영향을 받게 되고 Session ID 자체를 탈취당하여 해커가 Session ID를 가진 사용자인 척을 한다면.. 이것 또한 노출되는데 세션을 만료시켜 버리면 해결될 것 같기도 하다.

 

3. Token 인증

클라이언트가 서버에 요청(로그인) ➡️ 서버는 클라이언트에게 토큰을 발급 ➡️ 클라이언트가 요청을 보낼 때 요청 헤더에 토큰을 담아서 호출 ➡️ 서버는 유효한 토큰인지 체크하여 인증 과정 처리

 

Token은 클라이언트에서 저장하기 때문에 서버에 의존하지 않지만 Payload는 암호화되지 않기 때문에 중요한 정보를 담을 수 없고 탈취당하면 대처하기가 어렵기 때문에 토큰 유효기간을 짧게 둬서 관리하는 방법이 최우선이라고 한다.

 

그래서 Token 기반인 JWT를 사용한다고?

내 생각엔 Cookie를 보완할 수 있는 게 Session이라고 생각이 들고 Session을 보완할 수 있는 게 Token이라고 생각하기 때문에 Token 기반인 JWT를 대부분의 기업들에서 사용하는 이유라고 생각이 든다. 

 

왜냐하면 Cookie는 정보 그대로 클라이언트에 노출이 되는 단점을 Session이 Session ID로 보호하지만 서버에서 관리를 하기 때문에 서버 과부하 등.. 일어날 수 있는 단점을 Token으로 보완한다고 생각했고 물론 Token도 완벽한 방법은 아니라고 생각한다. 이 세상에 100%로 완벽한 시스템이 있을 수 없는 것처럼 허점은 당연히 존재한다라고 생각하고 그 허점을 보완할 수 있게끔 만드는 것이 개발자로서의 몫이라고 생각한다. 

 

그래서 나는 항상 JWT 인증할 때 아래의 프로세스를 생각하면서 개발했었고, 실무에서도 아래와 같은 방식으로 사용된 걸로 기억하고 있다. 

 

✅ 클라이언트: 회원 가입한 정보로 로그인을 시도한다.
✅ 서버: Phone과 Paswword 유효성 검사 후 JWT Token을 발급하여 클라이언트에 리턴해준다.
✅ 클라이언트: 클라이언트는 Token이 필요한 요청마다 Header에 JWT Token을 같이 보낸다.
✅ 서버: Header에 JWT Token이 존재하는지, 유효한지 검사하여 응답을 보낸다.

 

그래서 JWT가 뭔데?

JWT(JSON Web Token)은 JWT Token을 HTTP 헤더에 담아서 서버가 클라이언트를 식별하며, JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것이다. 그렇기 때문에 위변조 방지를 위해 개인키를 통한 전자서명이 들어있다. 구조는 아래처럼 세 가지로 구분되어 있는 문자열의 조합이다.

 

XXXXXX.YYYYYY.ZZZZZZ
Header(헤더).Payload(내용).Signature(서명)

 

jwt 예시 이미지

 

위에 이미지를 보면 Header에는 JWT에서 사용할 알고리즘 종류와 타입이, RayLoad에는 사용자의 정보가, 마지막 Signature에는 Header와 Payload를 Base64 URL-sage Encode를 한 이후 Header에 명시된 해시함수를 적용하고 개인키로 서명한 전자서명이 담기게 된다.

 

근데 결론은 인증이 목적이지 암호화가 아니기 때문에 정보 보호 목적이 아니라는 것을 명심하도록! 해당 토큰의 정보 중요도가 아니라 유효한 토큰인지만을 확인하면 되는 문제이다. 여기서 어디서 암호 어쩌구 이런 문장을 봐버려서 암호화라는 이상한 답변을 한 나처럼.. 확실히 알고 갔으면 좋겠다.

 

즉, 정보 보호 목적이 아니므로 Payload에 민감한 정보는 넣으면 안 된다! 이 방법도 탈취의 위험이 존재하기 때문에 많은 사람들이 Access Token, Refresh Token으로 나눠서 Access Token의 만료 기한을 짧게 두고 만료되면 Refresh Token을 발급하면서 인증할 수 있게끔 한다고 한다. 직접적으로 사용해보진 않아서 나중에 사용하게 된다면 다시 글을 정리해 볼 예정이다!

 

그래서 결론적으로 JWT(Json Web Token)를 왜 써야 하는데?

이 글을 쓰게 된 핵심 문제였고 내용을 정리하면서 계속 생각했을 때 지금의 답변은 " state-ful 상태로 유지하기 위하여 사용하게 되었으며 인증 정보에 대한 별도의 저장소가 필요 없이 사용할 수 있다는 점에서 사용하게 되었습니다."로 대답할 수 있을 것 같다. 사실 이 답변도 너무 간단하다고 생각하지만 Cookie와 Session이 아닌 JWT를 사용하는 이유에서 가장 와닿았기 때문이고 앞으로 더 고민하고 생각해봐야 할 문제인 것 같다.

 

아직 100% 만족하는 답변이 아니지만 그래도 면접에서의 그 한 질문이 나를 돌아보게 되었고 프로젝트마다 사용했는데 위 내용에서 알고 있던 사실조차 제대로 말한 부분이 없었기 때문에 반성하면서 앞으로는 했던 것도 되새기는 연습을 해야 될 것 같다!

 

 

 

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io