React + Express로 JWT 방식 회원기능 구현하기 (1)

mhlog·2023년 4월 22일
1

React

목록 보기
4/10
post-thumbnail

이번 포스팅에서는 Session과 JWT의 차이점, 장단점에 대해서 포스팅하고, 다음 포스팅에서 내가 이해한 React + Express로 JWT를 구현하는 방법에 작성하려고 한다

Session VS JWT

Session-based Authentication

  • 세션은 브라우저와 웹 서버가 연결되어 브라우저가 종료될 때까지의 시점이다. 브라우저를 통해 서버에 접속할 때 서버는 세션 id를 쿠키에 담아 되돌려주고, 사용자는 세션 id를 담은 쿠키인 세션 쿠키를 이 후 요청부터 계속해서 함께 전달함으로 서버가 클라이언트를 식별할 수 있게 하는 기술이 세션 기반 인증 방식인데 보통 세션이라고 한다.

  • 클라이언트가 HTTP요청을 보낼 때 쿠키에 세션 id가 없다면 서버는 세션 id를 생성 해 쿠키에 담아서 돌려준다. 다시 HTTP 재요청을 할 때 쿠키를 보내기 때문에 서버에서는 세션 id를 통해 클라이언트를 식별할 수 있는 것이다.

전체적인 Flow는 다음과 같다.

  1. 로그인시 제출한 아이디, 비밀번호가 DB에 저장된 회원정보와 맞다면 세션스토어에 Session을 하나 만들어서 저장한다. (여기서 세션스토어는 DB가 될 수도 있고 서버 메모리가 될 수도 있음) Session은 쉽게 말해서 Client가 언제 어디서 로그인 했는지에 대한 정보를 담은 자료이다.
  2. 로그인 한 유저마다 각각 유니크한 세션아이디를 발급한다.
  3. 발급한 세션아이디는 쿠키에 담아서 고객 브라우저에 전송해준다. 세션아이디는 고객과 서버 둘다 보관한다. (쿠키란 브라우저에 마련되어 있는 작은 문자데이터 저장공간이다. 여기에 세션아이디가 abc123 이렇게 기록이 된다.)
  4. 이제 Client가 myPage와 같은 로그인이 필요한 페이지를 접속하고자 한다면 페이지를 보여주기 전에 로그인을 하였는지를 확인하는 미들웨어를 실행합니다.
  5. 고객이 페이지를 요청할 때 마다 자동으로 쿠키가 서버로 전송되게 되는데, 서버는 쿠키에 기록된 세션아이디를 세션스토어(서버메모리 or DB)에 저장되어 있던 세션아이디와 비교해서 있으면 마이페이지를 보여준다.

장점

  • 서버에서 클라이언트의 상태를 유지하고 있으므로, 사용자의 로그인 여부 확인이 용이하고, 경우에 따라서 강제 로그아웃 등의 제재를 가할 수 있다.
  • 클라이언트가 임의로 정보를 변경시키더라도 서버에서 클라이언트의 상태 정보를 가지고 있으므로 상대적으로 안전하다.

단점

  • 서버에서 클라이언트의 상태를 모두 유지하고 있어야 하므로, 클라이언트 수에 따른 메모리나 DB 부하가 심하다.
  • 사용자가 많아지는 경우 로드 밸런싱을 통한 서버확장을 이용해야 하는데 이때 세션관리가 여려워진다.
  • 웹 브라우저에서 세션 관리에 사용하는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 CORS 방식(여러 도메인에 request를 보내는 브라우저)을 사용할 때 쿠키 및 세션 관리가 어렵다.
  • 멀티 디바이스 환경(모바일, 브라우저 공동 사용 등)에서 로그인 시 중복 로그인 처리가 되지 않는 등의 신경 써줘야 할 부분들이 생긴다.

JSON Web Token (JWT)

  • 토큰 방식은 세션데이터를 서버에 저장하지 않고, 마이페이지를 열람할 수 있는 열쇠(토큰)을 사용자에게 쥐어주는 것이다.
  • 따라서 토큰에는 session 방식보다 더 많은 정보가 들어간다. (이름, 아이디, 유효기간 등)
  • JWT 토큰에는 Header, Payload, Signature 구조로 이루어져 있다. JWT는 암호화되지 않아서 쉽게 Decoding이 가능하기 때문에 Payload(Data)에는 최소한의 정보만 담아야 한다.

전체적인 Flow는 다음과 같다.

  1. 로그인시 제출한 아이디와 비밀번호가 DB에 저장된 회원정보와 맞다면 서버는 Token을 하나 만들어서 고객 브라우저로 보낸다.
  2. 클라이언트가 마이페이지를 요청하면 서버는 마이페이지를 보여주기위해서 토큰 검사를 수행한다. 고객이 마이페이지 요청시 함께 보낸 Token이 적법한지 등을 검사한다. 유통기한이 지나지는 않았는지, Signature는 올바르게 되어 있는지 등의 검사를 거친 후 이상이 없으면 마이페이지를 보여준다.

장점

  • stateless하다. 서버측 부하를 낮출 수 있고 독립적이기 때문에 능률적으로 접근 권한관리를 할 수 있고 분산/클라우드 기반 인프라 스트럭처에 잘 대응할 수 있다.
  • 별도의 인증 저장소가 필요하지 않다. 인증서버와 db에 의존하지 않아도 된다.

단점

  • JWT는 Decoding이 매우 쉽다. 민감한 유저의 정보는 집어넣지 않는다. 최소한의 정보만 넣어야함.
  • Signature의 SecretKey를 때려 맞추기 매우 쉽다. 이를 brute force attack이라 한다. 따라서 SecretKey를 매우 길고 보안성이 뛰어나게 설정해야한다. 보안성을 더욱 더 신경쓰고 싶으면 생성용키와 검증용키를 사용하여 운영한다. (JWT 라이브러리 이용)
  • JWT가 수명이 길어서 제 3자에게 탈취당할 경우가 발생할 수 있다. 그런데 JWT는 서버가 발급하고 나면 JWT를 관리하지 않기 때문에 유효기간이 끝날때 까지 해커는 계속 사용이 가능하다. 이를 보완한 방법 중 하나로 access token & refresh token 방식이 있는데 두개의 토큰 모두 JWT이다.

RefreshToken & AccessToken

access token & refresh token 방식은 토큰들에 유효기간을 주어서 보안을 강화시킨 것이다. access token은 유효기간이 짧은 토큰이고, refresh token은 access token보다 유효기간이 긴 토큰이다.

  • 사용자가 로그인을 하면 서버로부터 access token, refresh token 2개의 토큰을 받는다. 이때 서버는 refresh token을 안전한 저장소에 저장한다.
  • 서버로부터 받은 access token의 유효 기간이 지나지 않은 경우 사용자가 어떤 요청을 보낼 때 access token을 함께 보내고 서버는 유효한 지 확인 후 응답을 보낸다.
  • 서버로부터 받은 access token의 유효 기간이 지난 경우 사용자는 refresh token과 함께 요청을 보내고, 저장소에 저장되어 있던 refresh token과 비교한 후에 유효하다면 새로운 access token과 응답을 함께 보낸다.

참고

https://millo-l.github.io/Session-%EA%B8%B0%EB%B0%98-%EC%9D%B8%EC%A6%9D%EB%B0%A9%EC%8B%9D/
https://80000coding.oopy.io/1f213f10-185c-4b4e-8372-119402fecdd0
https://velog.io/@gotaek/%EC%84%B8%EC%85%98Session%EA%B3%BC-JWT

0개의 댓글