배움 기록_실무 ✏️

JWT에 대해서

j_estory 2022. 1. 10. 12:24

1. JWT 탄생 배경

**1) HTTP 프로토콜은 Stateless로 동작합니다. → 새 요청마다 다시 인증을 해야 합니다.**

  • 위의 문제를 해결하기 위한 전통적인 방법은 SSS(server side session)를 사용하는 것입니다.

2) SSS 방법 시나리오

 

  • 해당 시나리오 에서는 먼자 사용자의 이름과 비밀번호를 확인합니다.
  • 해당 사용자가 인증이 된 경우, 서버는 세션 ID를 메모리에 저장하고 해당 ID를 클라이언트에게 반환합니다.
  • 그 이후의 요청에 대해서는 클라이언트를 식별하기 위해 세션ID를 서버로 보내면 됩니다.
  • 결과적으로 → SSS 방법을 이용하게 되면 데이터베이스에 대한 인증요청 수가 줄어듭니다.

2-1) 해당 시나리오의 문제점 → 확장에 대한 문제

  • API 시대에 있어 엔드 포인트가 많은 요청에 직면할 경우 인프라의 확장이 필요합니다.
  • 인프라 확장 스케일링에는 두가지 유형이 있습니다.
    • 수직 확장 : 서버에 더 많은 리소스를 추가 → 한계점이 낮은 비싼 솔루션
    • 수평 확장 : 로드 밸런서 뒤에 새 서버를 추가하는 것을 의미 → 간단하고 비용면에서 효과적

2-2) 수평 확장 시, 문제점 발생

  1. 초기 시나리오

  • 로드 밸런서 뒤에있는 단일 서버, 요청의 세션 ID는 서버 메모리에서 찾을 수 있다.
  1. 인프라 확장 시나리오

  • 새로운 서버가 로드 밸런서 뒤에 있으며 이전 세션에 대해 아무것도 모르므로 사용자가 인식되지 않습니다.
  • 새로운 서버의 메모리에는 xyz 세션이 없으므로 인증 프로세스가 실패합니다.
  • 해당 문제를 해결하기 위한 방안 → JWT 토큰 사용!!!

2. JWT 토큰의 구조

  • jwt 토큰은 본질적으로 인코딩 된 긴 텍스트 문자열입니다.
  • (.) 기호를 사용하여 구분된 세 개의 작은 부분으로 구성됩니다.
    • 헤더(header)
    • 페이로드(payload) 또는 바디(body)
    • 서명(signature)
  • 따라서 토큰은 header.payload.signature 이렇게 구성되어 있습니다.
    • jwt 토큰을 어떻게 해석해야 하는지를 알려주는 부분입니다.
    • typ, alg 두가지 정보로 구성되어 있습니다.

    • 위의 정보는 jwt 헤더를 디코딩했을 때 보여지는 예시입니다.
      • alg : 알고리즘 장식을 지정, 서명 및 토큰 검증에 사용합니다.
      • typ : 토큰의 타입을 지정합니다.
    2) 내용(payload)
      • payload에 있는 속성들을 claim 이라고 부른다.
      • 클래임의 종류
        • 등록된 클래임 (registered claims)
        • 공개 클래임 (public claim)
        • 비공개 클래임 (private claim)
      • [ ] 등록된 클래임
        • 토큰 정보를 표현하기 위해서 이미 정해진 종류의 데이터들로, 모두 선택적으로 작성이가능하며 사용할 것을 권장한다.name, value 쌍으로 이루어져 있다.
      • [ ] 공개 클래임
        • 사용자 정의 클래임으로, 공개용 정보를 위해서 사용된다.
        • 충돌 방지를 위해서 URL 포맷을 이용한다.
      • [ ] 비공개 클래임
        • 사용자 정의 클래임으로, 서버와 클라이언트 사이에 임의로 지정한 정보를 저장한다.
        • 보통 사용자의 정보(userid, name ... ) 등이 들어간다.
    3) 서명(signature)
    • 서명은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다.
    • 서명은 위에서 만든 header와 payload의 값을 각각 인코딩하고, 인코딩한 값을 비밀 키를 이용하여 header에서 정의한 알고리즘으로 해싱을 하고 이 값을 다시 인코딩하여 생성한다.
  • 1) 헤더(header)
  • 생성된 토큰의 예시

  • 생성된 토큰은 HTTP 통신을 할 때 Authorization이라는 key의 value로 사용된다.

{ "Authorization" : "Bearer {생성된 토큰 값}" }

3. JWT 토큰을 이용한 인증 과정

  • 사용자가 id와 password를 입력하여 로그인을 시도합니다.
  • 서버는 요청을 확인하고 secret key를 통해 Access token을 발급합니다.
  • jwt 토큰을 클라이언트에 전달 합니다.
  • 클라이언트에서 api를 요청할 때, 클라이언트가 Authorization header에 Access token을 담아서 보냅니다.
  • 서버는 JWT Signature를 체크(중간에 위변조 여부를 확인하기 위해)하고 payload로 부터 사용자 정보를 확인하여 요청에 맞는 데이터를 반환합니다.
    • 클라이언트의 로그인 정보를 서버 메모리에 저장하지 않기 때문에 토큰기반 인증 메커니즘을 제공합니다.
    • jwt에는 필요한 모든 정보를 토큰에 포함하기 때문에 데이터베이스와 같은 서버와의 커뮤니케이션 오버 헤드를 최소화 할 수 있습니다.
    • CORS는 쿠키를 사용하지 않기 때문에 jwt를 채용 한 인증 매커니즘은 두 도메인에서 API를 제공하더라도 문제가 발생하지 않습니다.
    • 처음 사용자를 등록할 때, Access token과 Refresh token이 모두 발급되어야 한다.
      • Access Token
        • 리소스에 직접 접근할 수 있도록 해주는 정보만을 갖고 있습니다.
        • Refresh Token에 비해서 짧은 만료 기간을 가지고 있습니다.
        • 주로 session에 담아서 관리한다.
      • Refresh Token
        • 새로운 Access Token을 발급하기 위한 정보를 갖습니다.
        • 클라이언트가 Access Token이 없거나 만료되면 Refresh Token을 통해 서버에 요청해서 새로운 Access Token을 발급 받을 수 있습니다.
        • Access Token에 비해서 긴 만료 기간을 가지고 있습니다.

4. JWT 활용 방안

  • 회원 인증
    • jwt를 사용하는 가장 흔한 시나리오이다.
    • 사용자가 로그인을 하면, 서버는 사용자의 정보를 기반으로한 토큰을 발급합니다.
    • 그 후, 사용자가 서버에 요청을 할 때 마다 jwt를 포함하여 전달합니다.
    • 서버는 클라이언틍에서 요청을 받을때 마다, 해당 토큰이 유효하고 인증됐는지 검증을 하고, 사용자가 요청한 작업에 권한이 있는지 확인하여 작업을 처리합니다.
    • 서버에서는 사용자에 대한 세션을 유지 할 필요가 없습니다. 즉, 사용자가 로그인되어 있는지 안되어 있는지 신경 쓸 필요가 없고, 사용자가 요청을 했을 때 토큰만 확인하면 되므로 세션 관리가 필요 없기 때문에 서버 자원과 비용을 절감할 수 있습니다.
  • 정보 교류
    • jwt는 두 개체 사이에서 안정성있게 정보를 교환하기에 좋은 방법입니다.
    • 그 이유는, 정보가 서명이 되어있기 때문에 정보를 보낸이가 바뀌진 않았는지, 또 정보가 도중에 조작되지는 않았는지 검증할 수 있습니다.

5. JWT 장점과 단점

1) 장점

  • 훌륭한 확장성
    • 만약, 세션을 이용한다면 스케일 아웃(서버 확장)을 할 때마다 각 서버마다 세션 정보를 저장하게 됩니다.
      • ex) 사용자1이 서버1에서 로그인 인증을 받았습니다.
      • 그동안 사용자가 증가하여 서버2로 스케일 아웃이 일어났습니다.
      • 그러나, 서버2는 사용자1이 로그인 했는지 여부를 알 수 없습니다.
    • 즉, 서버가 늘어나도 토큰을 인증하는 방식만 알고 있다면 사용자 인증에 문제가 없습니다.
    • jwt를 사용하지 않고 세션 전용 서버를 만들어 db에 저장하는 방법도 있습니다.
      • 그러나, 사용자의 인증이 필요한 api의 모든 요청에 대해서 서버에 조회를 해서 db의 값을 읽어야 하기에 db 부하를 만들 수 있습니다.
  • 보안성
    • 클라이언트가 서버로 요청할 때 쿠키를 전달하지 않기 때문에 쿠키를 사용함으로써 발생하는 취약점이 사라집니다.
      • 쿠키는 클라이언트에 저장되는 key-value 형태로 이루어진 데이터입니다.
      • 이러한 쿠키의 문제점은 사용자 인증에 대한 정보를 모두 클라이언트가 가지고 있기 때문에 http 요청을 탈취당할 경우 쿠키 자체를 탈취당해 사용자 정보를 모두 빼앗길 수 있습니다.
      • 이러한 쿠키의 단점을 해결해주는 방법이 jwt 토큰이라고 할 수 있습니다.
  • 여러 도메인
    • 서버 기반 인증 시스템의 문제인 CORS 문제를 해결합니다.
    • 쿠키는 발행한 서버에서만 유효합니다.
      • 서버1에서 발행한 토큰은 서버2에서는 사용할 수 없습니다.
      • 하지만 jwt는 어떤 도메인에서도 토큰만 유효하다면 처리가 가능합니다.
    • 최근 시대의 흐름에 따라 스마트폰, 태블릿 같이 다양한 모바일 기기로 접근하는 경우, 쿠키를 사용할 경우, 브라우저의 쿠키 처리 방법과 모바일 기기의 쿠키 처리 방법은 상이합니다.
    • 따라서 jwt를 이용하는 것이 다양한 디바이스 지원에서 유리합니다.웹, 앱 간의 상이한 쿠키 세션 처리
    •  
    •  
    • 2) 단점
  • 데이터 증가에 따른 네트워크 부하 증가
    • 모든 요청에 대해서 토큰이 전송되므로 토큰에 담기는 정보가 증가할 수록 네트워크 부하가 증가합니다.
  • self-contained
    • 토큰 자체에 모든 정보를 담고 있습니다.
    • jwt가 만료시간 전에 탈취당하면 서버에서 할 수 있는것이 없습니다.
  • payload 인코딩
    • 페이로드 자체는 암호화된것이 아니라 인코딩 된 것 입니다.
    • 중간에 페이로드를 탈취하여 디코딩하면 데이터를 볼 수 있으므로 중요한 데이터를 넣지 말아야 합니다.
  • Stateless
    • jwt는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능합니다.
    • 토큰을 임의로 삭제하는 것이 불가능하므로 만료 시간을 꼭 넣어주어야 합니다.

'배움 기록_실무 ✏️' 카테고리의 다른 글

구글 OAuth2 인증 방식  (0) 2022.03.29
OAuth 동작 방식  (1) 2022.03.29
쿠팡 파트너스 API 연동  (2) 2022.02.28
Spring batch 개발  (4) 2022.02.10
AWS SQS  (1) 2021.04.16