‘페스타고’ 서비스에서는 사용자가 ‘티켓 제시’ 버튼 클릭시, 30초간 유효한 QR코드 창이 활성화된다.
그리고, 우리 팀은 QR코드의 데이터로 JWT을 고려하고 있다.

JWT에 대한 설명은 아래 포스팅을 참고하자.
JWT란?
'페스타고' 프로젝트를 진행하며 JWT를 활용할 일이 생겼다. JWT의 구성요소에 대해 알아보자. JWT 구성요소 JWT의 구성요소 3가지는 .으로 구분된다. Header Payload Signature 각 구성요소별 특징을 알아
xxeol.tistory.com
🌧️ UUID를 사용했을 때의 문제점
JWT 이전에는 QR코드 식별자로 JWT대신 UUID를 고려했다.
UUID는 랜덤하게 생성된 코드로, 그 자체로 데이터를 담지 못한다.
즉, 해당 코드가 어떤 티켓의 코드인지 정보와 코드의 유효기간을 코드만으로는 알아낼 수 없다.
따라서 이를 DB에 데이터로 보관해야한다.
아래는 예시 테이블 구조이다.
UUID | 티켓id | 만료 일자 |
c1938c86-83c1-46c2-bb9d-d44150f6df28 | 1 | 2023-07-11T23:13:10 |
7eacd4de-b0e4-425d-91cc-fbd2d6a81472 | 2 | 2023-07-11T23:15:42 |
즉, UUID로 티켓id와 유효 시간 정보를 알기 위해서는 DB 접근이 필요한데, 그로인해 다음과 같은 문제점들이 발생했다.
DB 접근 비용
QR을 생성하고, 티켓을 검사할 때 마다 DB를 접근해야 한다.
입장 시간이 같은 사용자들은 동시간에 QR 생성 요청을 보낼 것이다.
따라서, 동시다발적으로 많은 DB 접근이 발생해 DB의 부담이 커진다.
또한, DB를 접근하는데 드는 비용만큼 요청의 응답 시간이 길어진다.
유효기간이 지난 데이터의 삭제
30초만 유효한 정보를 DB에 저장해야한다.
QR코드는 30초마다 갱신되므로, 기존 데이터는 30초가 지나면 유효하지 않은 상태가 된다.
따라서, 유효 기간이 지난 데이터를 어떻게 삭제할 것인지 고민해야 한다. (Redis의 도입을 고려해야한다.)
하지만 JWT를 도입했을 때 위 문제점들을 해결할 수 있었다.
☀️ JWT를 도입하고자 하는 이유
우리가 JWT를 도입하고자 하는 이유는 아래와 같다.
1. self-contained
JWT의 self-contained한 성격 때문에 DB 접근이 불필요해진다.
(JWT는 자체적으로 필요한 정보들을 담을 수 있다.)
2. 유효기간 관리에서의 용이함
JWT의 payload에 exp 클레임 값으로 만료일자를 설정해줌으로써 유효기간을 관리할 수 있다.
또한, JWT는 DB에 저장되지 않는 단순 문자열이므로 따로 삭제 연산을 수행할 필요가 없다.
그저 요청으로 받은 JWT 토큰의 exp 값을 현재 시간과 비교해 만료여부를 판단하면 끝이다.
3. JWT 단점 피해가기
3-1. 민감하지 않은 정보들
우리가 QR코드를 통해 얻고 싶은 내용들은 (티켓id, QR코드 만료 시간)과 같은 민감하지 않은 정보들이다.
따라서, JWT에 담아도 보안적으로 문제가 되지 않는다.
3-2. 토큰을 강제 만료 시켜야하는 경우의 부재
JWT 토큰의 단점 중 하나가, 토큰을 강제 만료시킬 수 없다는 점이다.
하지만, 우리 서비스의 경우 토큰을 강제 만료 시켜야할 일이 없다.
기존의 QR코드가 유효한 상태에서 QR코드 재발급 요청이 들어와도, 기존의 코드를 비활성화 시키지 않기 때문이다.
3-3. 탈취의 리스크가 작다
JWT 토큰의 유효 시간이 30초로 매우 짧다.
따라서 탈취를 당하더라도 그 시점에 토큰이 유효하지 않을 가능성이 크다.
또한, 일회성 토큰이다. 사용 즉시 티켓의 상태가 변화하기 때문에 토큰을 재사용할 수 없다.
또한 QR 확인만을 위한 토큰이므로, 해당 토큰으로 서비스의 다른 기능을 사용할 수 없다.
즉, 유효한 토큰이 있더라도 개인 정보 등과 같은 민감한 정보를 알아낼 수 없다.
‘페스타고’ 서비스에서는 사용자가 ‘티켓 제시’ 버튼 클릭시, 30초간 유효한 QR코드 창이 활성화된다.
그리고, 우리 팀은 QR코드의 데이터로 JWT을 고려하고 있다.

JWT에 대한 설명은 아래 포스팅을 참고하자.
JWT란?
'페스타고' 프로젝트를 진행하며 JWT를 활용할 일이 생겼다. JWT의 구성요소에 대해 알아보자. JWT 구성요소 JWT의 구성요소 3가지는 .으로 구분된다. Header Payload Signature 각 구성요소별 특징을 알아
xxeol.tistory.com
🌧️ UUID를 사용했을 때의 문제점
JWT 이전에는 QR코드 식별자로 JWT대신 UUID를 고려했다.
UUID는 랜덤하게 생성된 코드로, 그 자체로 데이터를 담지 못한다.
즉, 해당 코드가 어떤 티켓의 코드인지 정보와 코드의 유효기간을 코드만으로는 알아낼 수 없다.
따라서 이를 DB에 데이터로 보관해야한다.
아래는 예시 테이블 구조이다.
UUID | 티켓id | 만료 일자 |
c1938c86-83c1-46c2-bb9d-d44150f6df28 | 1 | 2023-07-11T23:13:10 |
7eacd4de-b0e4-425d-91cc-fbd2d6a81472 | 2 | 2023-07-11T23:15:42 |
즉, UUID로 티켓id와 유효 시간 정보를 알기 위해서는 DB 접근이 필요한데, 그로인해 다음과 같은 문제점들이 발생했다.
DB 접근 비용
QR을 생성하고, 티켓을 검사할 때 마다 DB를 접근해야 한다.
입장 시간이 같은 사용자들은 동시간에 QR 생성 요청을 보낼 것이다.
따라서, 동시다발적으로 많은 DB 접근이 발생해 DB의 부담이 커진다.
또한, DB를 접근하는데 드는 비용만큼 요청의 응답 시간이 길어진다.
유효기간이 지난 데이터의 삭제
30초만 유효한 정보를 DB에 저장해야한다.
QR코드는 30초마다 갱신되므로, 기존 데이터는 30초가 지나면 유효하지 않은 상태가 된다.
따라서, 유효 기간이 지난 데이터를 어떻게 삭제할 것인지 고민해야 한다. (Redis의 도입을 고려해야한다.)
하지만 JWT를 도입했을 때 위 문제점들을 해결할 수 있었다.
☀️ JWT를 도입하고자 하는 이유
우리가 JWT를 도입하고자 하는 이유는 아래와 같다.
1. self-contained
JWT의 self-contained한 성격 때문에 DB 접근이 불필요해진다.
(JWT는 자체적으로 필요한 정보들을 담을 수 있다.)
2. 유효기간 관리에서의 용이함
JWT의 payload에 exp 클레임 값으로 만료일자를 설정해줌으로써 유효기간을 관리할 수 있다.
또한, JWT는 DB에 저장되지 않는 단순 문자열이므로 따로 삭제 연산을 수행할 필요가 없다.
그저 요청으로 받은 JWT 토큰의 exp 값을 현재 시간과 비교해 만료여부를 판단하면 끝이다.
3. JWT 단점 피해가기
3-1. 민감하지 않은 정보들
우리가 QR코드를 통해 얻고 싶은 내용들은 (티켓id, QR코드 만료 시간)과 같은 민감하지 않은 정보들이다.
따라서, JWT에 담아도 보안적으로 문제가 되지 않는다.
3-2. 토큰을 강제 만료 시켜야하는 경우의 부재
JWT 토큰의 단점 중 하나가, 토큰을 강제 만료시킬 수 없다는 점이다.
하지만, 우리 서비스의 경우 토큰을 강제 만료 시켜야할 일이 없다.
기존의 QR코드가 유효한 상태에서 QR코드 재발급 요청이 들어와도, 기존의 코드를 비활성화 시키지 않기 때문이다.
3-3. 탈취의 리스크가 작다
JWT 토큰의 유효 시간이 30초로 매우 짧다.
따라서 탈취를 당하더라도 그 시점에 토큰이 유효하지 않을 가능성이 크다.
또한, 일회성 토큰이다. 사용 즉시 티켓의 상태가 변화하기 때문에 토큰을 재사용할 수 없다.
또한 QR 확인만을 위한 토큰이므로, 해당 토큰으로 서비스의 다른 기능을 사용할 수 없다.
즉, 유효한 토큰이 있더라도 개인 정보 등과 같은 민감한 정보를 알아낼 수 없다.