사용자 인증 - 토큰 (JWT)

adc0612·2022년 6월 29일
1

사용자 인증

목록 보기
2/2

JWT (JSON Web Token)

  • JWT는 전자 서명(JSON 의 변조를 체크가능) 된 URL-safe (URL로 이용할 수 있는 문자만 구성된)의 JSON이다.
  • JWT는 HMAC 알고리즘을 사용하여 비밀키 또는 RSA를 이용한 Public Key/ Private Key 쌍으로 서명할 수 있다.
  • JWT는 서버와 클라이언트 간 정보를 주고 받을 때 HTTP request header에 JSON 토큰(access token)을 넣은 후 서버는 별도의 인증 과정 없이 헤더에 포함되어 있는 JWT 정보를 통해 인증한다.

JWT 구성


JWT는 세 파트(Header, Payload, Signature)로 구성된다.

  • Header
    Header는 토큰의 유형 (JWT)과 HMAC, SHA256 또는 RSA와 같은 해시 알고리즘을 가지고 있다.
  • Payload
    Payload는 사용자의 정보나 데이터 속성 등의 claim을 포함하고 있다. 서비스 측에서 사용자에게 이 토큰을 통해 공개하기 원하는 내용이 들어간다.
  • Signature
    Signature는 서명 부분으로, Header + Payload + <서버에 감춰둔 Secret Key> 을
    Header의 알고리즘에 넣고 돌리면 Signature값이 나온다.

토큰 인증 (token)

토큰 기반의 인증 시스템은 인증받은 사용자들에게 토큰을 발급하고, 서버에 요청을 할 때 헤더에 토큰을 함께 보내도록 하여 유효성 검사를 한다.
더이상 사용자의 인증 정보를 서버나 세션에 유지하지 않고 클라이언트 측에서 들어오는 요청만으로 작업을 처리한다.
즉, 서버 기반의 인증 시스템과 달리 상태를 유지하지 않으므로 Stateless한 구조를 갖는다.

인증 과정


1. 사용자가 로그인을 성공하면 서버에서 JWT형태의 암호화된 토큰을 발급(생성)한다.
2. 생성된 토큰(암호화 된 JWT)를 클라이언트(브라우저에 보낸다.
3. 사용자의 local storage에 JWT(access token, refresh token)를 저장한다.
4. 브라우저는 모든 request의 헤더에 access token을 함께 전송한다.
5. 서버는 클라이언트(브라우저
가 보낸 access token을 식별하고 유효하다면, 원하는 응답을 제공해준다.

Access Token, Refresh Token

JWT는 서버 측에서 토큰을 추적하는 게 아니기 때문에 편리할 수 있으나, 그렇기 때문에 토큰을 탈취당하면, 토큰을 무효화할 방법이 없다.
방지하기 위해 토큰의 수명을 30분 정도로 짧게 잡을려고 한다.
그렇게 되면 사용자는 자주 로그인을 통해 토큰을 재발급 받아야 한다. (사용성 불편)
그래서 토큰을 Acess Token과 Refresh Token 분리해서 전달한다.

Refresh Token은 Access Token과 똑같은 형태의 JWT이다. 처음에 로그인을 완료 했을 때 Access Token과 동시에 발급되는 Refresh Token은 긴 유효기간을 가지면서, Access Token이 만료 됐을 때 새로 발급해주는 key가 된다.

예시
Access Token은 유효기간이 30분, Refresh Token은 유효기간이 2주를 부여한다.
사용자는 로그인을 하고 Access Token과 Refresh Token을 받는다.
클라이언트는 Refresh Token을 안전한 곳(Local Storage) 에 저장하고, API 요청은 Access Token을 가지고 할 수 있다.
30분이 지나 토큰이 만료되면 Refresh Token을 서버에 보냄으로써 새로운 Access Token을 발급받을 수 있게 되고, 발급받은 Access Token으로 다시 API요청을 할 수 있게 된다.

Refresh token도 탈취 당하면 똑같이 보안상 취약점이 생긴다.
Access token이 api 요청 시마다 http통신을 통해 노출이 되는 반면, Refresh token은 Access token이 만료 됐을 경우만 네트워크 통신을 통해 서버로 보내기 때문에 탈취될 위험이 현저히 적다.

토큰 인증 장점

  • JWT를 클라이언트에서 저장하므로 서버의 메모리, DB 등의 부담이 없다.
  • 로드 밸런싱을 사용한 서버 확장이 용이하다.
  • 멀티 디바이스 환경에서 부담이 없다.
  • Access token의 만료 기간이 짧아 타인에게 도난당하더라도 안정성이 높다.
  • CORS 방식(여러 도메인에 request를 보내는 브라우저)을 사용하기 용이하다.

토큰 인증 단점

  • 서버에서 클라이언트의 상태를 저장하고 있지 않으므로, 사용자의 로그인 여부 확인, 경우에 따른 강제 로그아웃 등의 제재를 가하는 데 어려움이 있다.
  • 클라이언트가 임의로 토큰을 수정하거나 구조가 변경되게 되면 서버에서 확인할 수 없어 세션 방식에 비해 상대적으로 안정성이 낮다.
  • Refresh token이 도난됐을 경우 계속해서 Access token을 발급받으며 악용될 가능성이 있다.
  • 일반적으로 Payload 부분에 사용자의 필요한 모든 정보를 저장하는 경우가 많아 SessionId의 길이보다 길다. (즉, HTTP request가 무거워질 수 있다.)
  • XSS 공격에 취약할 수 있어 민감한 정보를 포함하는 경우 위험할 수 있다.

[참고] https://d-dual.tistory.com/3
[참고] https://velog.io/@hoo00nn/Token-%EC%9D%B8%EC%A6%9D-%EB%B0%A9%EC%8B%9D%EC%9D%B4%EB%9E%80
[참고] https://mangkyu.tistory.com/55
[참고] https://millo-l.github.io/JWT-%EA%B8%B0%EB%B0%98-%EC%9D%B8%EC%A6%9D%EB%B0%A9%EC%8B%9D/

0개의 댓글