JWT

Jnns·2023년 12월 24일
post-thumbnail

로그인 / 회원가입 페이지 구현 중에 궁금한 점이 생겼다.

Access Token과 Refresh Token이 정확히 뭐고 왜 필요하지?

보통 서버가 클라이언트 인증을 확인하는 방식은 대표적으로 쿠기, 세션, 토큰 3가지 방식이 있다.
토큰에 대해 알아보기 전에 간단히 짚고 넘어가자.

쿠키는 Key-Value 형식의 문자열 덩어리이다.
클라이언트가 웹사이트를 방문할 경우, 그 사이트의 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 정보 파일이다. 각 사용자마다 브라우저에 정보를 저장하니 고유 정보 식별이 가능하다.

쿠키 인증의 단점

  • 요청 시 쿠키의 값을 그대로 보내기 때문에 보안에 취약하다.
  • 그 외의 단점으로는 용량 제한이 있어 많은 정보를 담을 수 없고,
  • 웹 브라우저마다 쿠키에 대한 지원 형태가 다르기에 브라우저간 공유가 불가능하다.
  • 쿠키의 사이즈가 커질수록 네트워크에 부하가 심해진다.

Session 인증

쿠키의 보안적인 이슈 때문에 세션은 비밀번호 등 클라이언트의 민감한 인증 정보를 브라우저가 아닌 서버 측에서 저장하고 관리하는 것이다. 서버의 메모리에 저장하거나, 로컬 파일이나 DB에 저장하기도 한다.

세션 인증의 단점

  • 세션 ID 자체를 탈취하여 클라이언트인 척 위장할 수 있다.
    (서버에서 IP특정을 통해 해결 할 수 있다고 하는데 아직은 무슨 말인지 잘 모르겠다. 추가로 찾아보도록 하자.)
  • 서버에서 세션 저장소를 사용하므로 요청이 많아지면 서버 부하가 심해진다.

JWT란?

JWT(Json Web Token)은 Json 객체에 인증에 필요한 정보들을 암호화시킨(비밀 키로 서명한) 토큰으로,
JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 인터넷 표준 인증 방식이다.

JWT는 JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것이고, 토큰 내부에는 위변조 방시를 위해 개인키를 통한 전자서명도 들어있다.

JWT 구조

JWT는 . 을 기준으로 좌측부터 Header, Payload, Signature를 의미한다.

  • Header: JWT에서 사용할 타입과 해시 알고리즘의 종류가 담겨있다.
  • Payload: 서버에서 첨부한 사용자 권한 정보와 데이터가 담겨있다.
  • Signature: Header, Payload를 Base64 URL-safe Encode를 한 이루 Header에 명시된 해시함수를 적용하고, Private Key로 서명한 전자서명이 담겨있다.

JWT의 인증 과정

  1. 클라이언트는 ID, PW를 입력하여 서버에 로그인 인증 요청(POST)을 보낸다.

  2. 서버에서 클라이언트로부터 인증 요청을 받으면, Header, PayLoad, Signature을 정의한다. Hedaer, PayLoad, Signature를 각각 Base64로 한 번 더 암호화하여 JWT, Access Token, Refresh Token을 생성하고 이를 쿠키에 담아 클라이언트에게 발급한다.

  3. 클라이언트는 서버로부터 받은 JWT를 로컬 스토리지에 저장한다. (쿠키나 다른 곳에 저장할 수도 있다.)
    API를 서버에 요청할때 Authorization header에 Access Token을 담아서 보낸다.

  4. 서버는 Access Token을 검증하고 통과하면 데이터 응답을 보낸다.

  5. 클라이언트가 만료된 Access Token을 이용해 요청을 보내면 서버는 재발행요청을 한다.

  6. 재발행 요청은 만료된 Access Token과 유효한 RefreshToken 값을 URL/auth/reissue 로 POST 요청을 보낸다.

  7. 서버에서는 RefreshToken을 검증하고 다시 AccessToken과 RefreshToken 값을 사용자에게 넘겨준다.

토큰 인증의 신뢰성

다른 유저가 Payload를 임의로 수정했을 때, 수정한 토큰을 서버에 요청을 보내면 서버는 유효성 검사를 시행한다.
대조 결과가 일치하지 않으면 유저의 정보가 임의로 조작되었음을 알 수 있다.
서버는 토큰 안에 들어있는 정보가 무엇인지 아는 것보다 해당 토큰이 유효한 토큰인지 확인하는 것이 중요하다.

❗️주의할 점

JWT는 Base64로 암호화 하는데 디버거를 사용하면 인코딩 된 HWT를 1초만에 복호화할 수 있다.
그러므로 Payload에는 비밀번호와 같은 민감한 정보는 넣지 말아야 한다. 토큰의 목적은 정보 보호가 아닌, 위조 방지이다!!

JWT 장점

  • Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있다.
  • 인증 정보에 대한 별도의 저장소가 필요없다.
    -클라이언트 인증 정보를 저장하는 세션과 다르게, 서버는 무상태(StateLess)가 되어 서버 확장성이 우수해질 수 있다.
  • 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다. (쿠키와 차이)
  • 모바일 어플리케이션 환경에서도 잘 동작한다. (모바일은 세션 사용 불가능)

JWT 단점

  • Self-contained : 토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있다.
  • 토큰 길이 : 토큰의 Payload에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다.
  • Payload 인코딩 : payload 자체는 암호화 된 것이 아니라 BASE64로 인코딩 된 것이기 때문에, 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, payload에 중요 데이터를 넣지 않아야 한다.
  • Store Token : stateless 특징을 가지기 때문에, 토큰은 클라이언트 측에서 관리하고 저장한다. 때문에 토큰 자체를 탈취당하면 대처하기가 어렵게 된다.

Access Token & Refresh Token

JWT과 Access Token 뭔지 이제 좀 알겠다. 그럼 Refresh Token의 역할은 뭘까?

Access Token 만으로는 제 3자에게 탈취당할 경우 보안에 취약하다. JWT는 발급한 후 삭제가 불가능하기에, 토큰에 유효시간을 부여하는 식으로 탈취 문제에 대응해야 한다. 유효시간이 짧아질수록 보안에 좋겠지만, 그만큼 로그인을 자주 해서 Token을 새롭게 발급받아야 한다.

그래서 유효기간을 짧게 하면서 보안성을 높이기 위한 역할을 Refresh Token이 한다.
이름이 다르지만 형태 자체는 Refresh Token은 Access Token과 똑같은 JWT다. 단지 Access Token은 접근에 관여하는 토큰이고, Refresh Token은 재발급에 관여하는 토큰이다.

Access / Refresh Token 재발급

  1. 기본적으로 로그인 같은 과정을 하면 Access Token과 Refresh Token을 모두 발급하고, Refresh Token만 서버의 DB에 저장하고, 두 토큰 모두 쿠키 혹은 웹스토리지에 저장한다.

  2. 사용자가 인증이 필요한 API에 접근하고자 하면, 가장 먼저 토큰을 검사한다.

    • Access Token, Refresh Token 모두 만료 -> Error -> 재 로그인 후 둘 다 새로 발급

    • Access Token 만료, Refresh Token 유효 -> 클라이언트(쿠키, 웹스토리지)에 저장되어있는 refresh token과 서버 DB에 저장되어있는 refresh token 일치성을 확인한 뒤 access token 재발급

    • Access Token 유효, Refresh Token 만료 -> access token이 유효하다라는 것은 이미 인증된 것과 마찬가지니 바로 refresh token 재발급

    • Access Token, Refresh Token 모두 유효 -> 정상 처리

    1. 로그아웃을 하면 Access Token과 Refresh Token을 모두 만료시킨다.

출처:
https://inpa.tistory.com/entry/WEB-📚-JWTjson-web-token-란-💯-정리 [Inpa Dev 👨‍💻:티스토리],
https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-Access-Token-Refresh-Token-%EC%9B%90%EB%A6%AC-feat-JWT,
https://onejunu.tistory.com/137,
https://dreamcode.tistory.com/444?category=1050903

0개의 댓글