1. 개요


엔터프라이즈 환경에서 AP 인스턴스가 다중화되고 Stateless 기반의 시스템 구축이 보편화되면서 기존의 세션 기반 인증 대신 JWT(JSON Web Token) 기반 인증 방식이 많이 활용되고 있다. 특히, 클라우드 기반으로 RESTful Web Services, MSA 등 모던 아키텍처 환경에서 확장이 용이한 구성을 위해 주로 사용된다. 여기서는 JWT가 무엇인지 알아보고 현장의 업무요건에 대응할 수 있는 방안에 대해 살펴보고자 한다.

 

2. JWT(JSON Web Token)


JWT는 RFC7519에 정의된 웹 표준으로서 두 개체(클라이언트와 서버, 서비스와 서비스 등) 사이에서 JSON 포맷을 사용하여 가볍고 자가수용적(self-contained)인 방식으로 정보를 안전성 있게 전달할 수 있는 체계이다. 대부분의 주류 프로그래밍 언어에서 지원되며, URL에 대해 안전한 문자열로 구성되어 있기 때문에 HTTP 메시지 중 어디에든(URL, Header, Cookie 등) 위치할 수 있다.

JWT 는 '.'을 구분자로 3가지의 문자열로 구성되며, Header.Payload.Signature 형태의 구조로 되어 있다. 각 항목을 하나씩 살펴보기로 하자.

2.1. Header

Header는 두 가지 정보를 가지고 있다.

  • typ : 토큰의 타입을 지정하며 일반적으로 "JWT" 값을 가진다.
  • alg : 해싱 알고리즘을 지정하며 토큰을 검증 할 때 사용되는 Signature에서 사용된다.
  • 예시)
  • {
        "typ" : "JWT",
        "alg" : "HS256"
    }

2.2. Payload

Payload에는 토큰에 담을 정보가 들어가는데, 정보의 각 항목을 클레임(claim)이라 하고 이는 name/value의 쌍으로 구성된다. 토큰에는 여러 개의 클레임을 설정할 수 있다. 클레임은 다음과 같이 크게 세 가지로 구분된다.

  • registered 클레임 : 토큰에 대한 정보들을 담기 위해 이미 정해진 클레임
    - iss : 토큰 발급자 (issuer)
    - sub : 토큰 제목 (subject)
    - aud : 토큰 대상자 (audience)
    - exp : 토큰의 만료시간 (expiraton)
    - iat: 토큰이 발급된 시간 (issued at)
    - nbf : 토큰 활성 날짜 (not before)
    - jti: JWT의 고유 식별자로서 중복 방지용

  • public 클레임 : 사용자 정의 클레임으로서 공개용 정보를 위해 사용되며, 충돌 방지를 위해 URI 포맷을 이용
  •  
  • {
        "https://www.lgcns.com": true
    }
  • private 클레임 : 사용자 정의 클레임으로 클라이언트와 서버 사이에 임의로 지정한 정보를 저장
  • {
        "custom_name": "blah blah",
        "user_id": 1
    }

2.3. Signature

Header의 Base64 인코딩값Payload의 Base64 인코딩값을 '.'으로 연결하여 비밀키로 해시한 값이다. 이를 pseudo-code로 나타내면 다음과 같다.

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

 

이렇게 생성된 Header, Payload, Signature를 각각 Base64 인코딩하여 '.'으로 연결하면 최종적으로 JWT가 완성된다.

예시)

 

3. 세션과 JWT 기반 인증/인가 흐름도


세션과 JWT를 사용할 경우 각각의 인증/인가 절차를 비교하여 살펴본다.

  • 세션 기반 : 인증/인가 업무를 담당하는 인증 서비스가 세션 생성을 담당하고, 여러 서비스를 통합하는 진입점(예: API Gateway)에서 세션 유효성 확인
    << 로그인 시 똑같이 BE에서 세션을 생성하고, 다시 반환해주고, FE는 Session ID로 요청한다는 공통점이 있다. >>
    << Session을 발급할 뿐만 아니라, DB에 저장하기 때문에 ON/OFF 기능까지 줄 수 있다는 차이점이 존재한다.>>
  • JWT 기반 : 2중 토큰 체계(인증/인가용 Access 토큰, 갱신용 Refresh 토큰)를 토대로 인증 서비스가 토큰 발급하고 API Gateway에서 토큰 유효성 확인

 

4. 업무요건 대응


JWT 기반 인증/인가 적용 시 현장에서 발생할 수 있는 업무요건에 대한 대응방안을 살펴본다.

4.1. 일정 시간동안 시스템 미사용 시 재인증

사용자가 시스템 접속 후 일정 시간동안 아무런 동작(Action)이 없으면 재인증을 요구하는 업무요건이 있다. 이 경우 UI 동작방식에 따라 2가지 방안이 있을 수 있다.

  • UI에서 페이지 이동이 없는 경우 : SPA(Single Page Application) 구조인 경우 UI에서 Timer를 적용하여 만료시간을 체크한다.
  • UI에서 페이지 이동이 있는 경우 : 전통적인 HTML 페이지 이동 기반의 UI(MPA)인 경우 서버에서 최종 접속기록을 관리해야 한다.(Action이 있으면, 서버로 바로 전달이 된다.)

시스템의 UI 동작방식에 따라 적절한 방안을 적용하며, 각 방안에 따른 흐름은 다음과 같다.

 

4.2. 중복 로그인 방지

사용자가 특정 단말에서 로그인 후 다른 단말 또는 동일 단말의 다른 브라우저(브라우저 세션이 공유되지 않는 경우)에서 로그인하는 경우 먼저 로그인된 연결을 로그아웃 처리하는 요건이다. JWT의 registered 클레임에 존재하는 중복 방지를 위한 jti 항목을 활용할 수 있으며, 서버에서 중복 로그인이 감지되었을 때 처리하는 방식에 따라 2가지로 나누어 볼 수 있다.

  • Push 기반 : Push 서비스가 존재(BE -> FE로 신호)할 경우, 토큰의 jti로 강제 로그아웃 시킬 대상을 식별하여 Push 메시지를 보내 UI에서 로그아웃 시키는 방안
  • 토큰 저장소 기반 : 유효한 토큰의 jti를 별도의 저장소로 관리하여 로그인 시 업데이트하고, API Gateway에서 토큰의 jti를 체크하여 요청을 차단하는 방안

시스템의 구성에 따라 적절한 방안을 적용하며, 각 방안에 따른 흐름은 다음과 같다.

 

4.3. 야간 접속 차단

업무 시스템의 경우 야간에 접속할 수 있는 권한을 별도로 관리하여 권한을 보유한 사용자만 접속할 수 있도록 제한하는 업무요건이 있다. 이 경우, JWT의 registered 클레임에 존재하는 exp(만료시간) 항목을 활용할 수 있으며, 토큰 유효성을 검증하는 API Gateway에서 토큰 만료 시 요청을 차단하고 인증 서비스에서는 Refresh 토큰을 통한 갱신 요청 시 야간 접속권한에 따라 갱신을 거부할 수 있다.

 

5. 마무리


지금까지 JWT의 구조와 현장에서 발생할 수 있는 몇 가지 업무요건에 대한 대응방안에 대해 살펴보았다. JWT 자체로는 인증/인가를 위한 수단일 뿐, 세부적인 업무요건에 따라 인증/인가를 위한 서비스 기능 및 절차는 얼마든지 달라질 수 있으므로 현장의 요건을 명확히 정의하여 대응해야 한다. JWT를 신규 적용하고자 하는 프로젝트에서 방안 수립 시 도움이 될 수 있기를 바란다

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기