본문 바로가기

Tools

[JMeter] JWT 토큰 추출 및 헤더 추가

테스트 준비
  • 100명의 유저가 테스트를 한다고 가정하고 100개의 회원 가입 정보 준비하기
  • txt 파일 생성 코드
package org.example;

import java.io.FileWriter;
import java.io.IOException;

public class Main {
    public static void main(String[] args) {
        try {
            // 파일 작성용 FileWriter 생성
            FileWriter writer = new FileWriter("regist_data.txt");

            // 1부터 100까지 반복
            for (int i = 1; i <= 100; i++) {
                String email = "test" + i + "@example.com";
                String password = "1234";
                String username = "TEST" + i;
                String name = "Test Developer" + i;
                String phone = "010-1234-5678";
                String isActive = "true";

                // 한 줄의 데이터 생성
                String data = String.format("%s,%s,%s,%s,%s,%s%n", email, password, username, name, phone, isActive);

                // 파일에 작성
                writer.write(data);
            }

            // 파일 닫기
            writer.close();
            System.out.println("파일이 성공적으로 생성되었습니다.");
        } catch (IOException e) {
            System.out.println("파일 작성 중 오류가 발생했습니다.");
            e.printStackTrace();
        }
    }
}
test1@example.com,1234,TEST1,Test Developer1,010-1234-5678,true
test2@example.com,1234,TEST2,Test Developer2,010-1234-5678,true
test3@example.com,1234,TEST3,Test Developer3,010-1234-5678,true
test4@example.com,1234,TEST4,Test Developer4,010-1234-5678,true
test5@example.com,1234,TEST5,Test Developer5,010-1234-5678,true
test6@example.com,1234,TEST6,Test Developer6,010-1234-5678,true
test7@example.com,1234,TEST7,Test Developer7,010-1234-5678,true
test8@example.com,1234,TEST8,Test Developer8,010-1234-5678,true
test9@example.com,1234,TEST9,Test Developer9,010-1234-5678,true
test10@example.com,1234,TEST10,Test Developer10,010-1234-5678,true
test11@example.com,1234,TEST11,Test Developer11,010-1234-5678,true
test12@example.com,1234,TEST12,Test Developer12,010-1234-5678,true
test13@example.com,1234,TEST13,Test Developer13,010-1234-5678,true
test14@example.com,1234,TEST14,Test Developer14,010-1234-5678,true
test15@example.com,1234,TEST15,Test Developer15,010-1234-5678,true
test16@example.com,1234,TEST16,Test Developer16,010-1234-5678,true
test17@example.com,1234,TEST17,Test Developer17,010-1234-5678,true
test18@example.com,1234,TEST18,Test Developer18,010-1234-5678,true
test19@example.com,1234,TEST19,Test Developer19,010-1234-5678,true
test20@example.com,1234,TEST20,Test Developer20,010-1234-5678,true
test21@example.com,1234,TEST21,Test Developer21,010-1234-5678,true
test22@example.com,1234,TEST22,Test Developer22,010-1234-5678,true
test23@example.com,1234,TEST23,Test Developer23,010-1234-5678,true
test24@example.com,1234,TEST24,Test Developer24,010-1234-5678,true
test25@example.com,1234,TEST25,Test Developer25,010-1234-5678,true
test26@example.com,1234,TEST26,Test Developer26,010-1234-5678,true
test27@example.com,1234,TEST27,Test Developer27,010-1234-5678,true
test28@example.com,1234,TEST28,Test Developer28,010-1234-5678,true
test29@example.com,1234,TEST29,Test Developer29,010-1234-5678,true
test30@example.com,1234,TEST30,Test Developer30,010-1234-5678,true
test31@example.com,1234,TEST31,Test Developer31,010-1234-5678,true
test32@example.com,1234,TEST32,Test Developer32,010-1234-5678,true
test33@example.com,1234,TEST33,Test Developer33,010-1234-5678,true
test34@example.com,1234,TEST34,Test Developer34,010-1234-5678,true
test35@example.com,1234,TEST35,Test Developer35,010-1234-5678,true
test36@example.com,1234,TEST36,Test Developer36,010-1234-5678,true
test37@example.com,1234,TEST37,Test Developer37,010-1234-5678,true
test38@example.com,1234,TEST38,Test Developer38,010-1234-5678,true
test39@example.com,1234,TEST39,Test Developer39,010-1234-5678,true
test40@example.com,1234,TEST40,Test Developer40,010-1234-5678,true
test41@example.com,1234,TEST41,Test Developer41,010-1234-5678,true
test42@example.com,1234,TEST42,Test Developer42,010-1234-5678,true
test43@example.com,1234,TEST43,Test Developer43,010-1234-5678,true
test44@example.com,1234,TEST44,Test Developer44,010-1234-5678,true
test45@example.com,1234,TEST45,Test Developer45,010-1234-5678,true
test46@example.com,1234,TEST46,Test Developer46,010-1234-5678,true
test47@example.com,1234,TEST47,Test Developer47,010-1234-5678,true
test48@example.com,1234,TEST48,Test Developer48,010-1234-5678,true
test49@example.com,1234,TEST49,Test Developer49,010-1234-5678,true
test50@example.com,1234,TEST50,Test Developer50,010-1234-5678,true
test51@example.com,1234,TEST51,Test Developer51,010-1234-5678,true
test52@example.com,1234,TEST52,Test Developer52,010-1234-5678,true
test53@example.com,1234,TEST53,Test Developer53,010-1234-5678,true
test54@example.com,1234,TEST54,Test Developer54,010-1234-5678,true
test55@example.com,1234,TEST55,Test Developer55,010-1234-5678,true
test56@example.com,1234,TEST56,Test Developer56,010-1234-5678,true
test57@example.com,1234,TEST57,Test Developer57,010-1234-5678,true
test58@example.com,1234,TEST58,Test Developer58,010-1234-5678,true
test59@example.com,1234,TEST59,Test Developer59,010-1234-5678,true
test60@example.com,1234,TEST60,Test Developer60,010-1234-5678,true
test61@example.com,1234,TEST61,Test Developer61,010-1234-5678,true
test62@example.com,1234,TEST62,Test Developer62,010-1234-5678,true
test63@example.com,1234,TEST63,Test Developer63,010-1234-5678,true
test64@example.com,1234,TEST64,Test Developer64,010-1234-5678,true
test65@example.com,1234,TEST65,Test Developer65,010-1234-5678,true
test66@example.com,1234,TEST66,Test Developer66,010-1234-5678,true
test67@example.com,1234,TEST67,Test Developer67,010-1234-5678,true
test68@example.com,1234,TEST68,Test Developer68,010-1234-5678,true
test69@example.com,1234,TEST69,Test Developer69,010-1234-5678,true
test70@example.com,1234,TEST70,Test Developer70,010-1234-5678,true
test71@example.com,1234,TEST71,Test Developer71,010-1234-5678,true
test72@example.com,1234,TEST72,Test Developer72,010-1234-5678,true
test73@example.com,1234,TEST73,Test Developer73,010-1234-5678,true
test74@example.com,1234,TEST74,Test Developer74,010-1234-5678,true
test75@example.com,1234,TEST75,Test Developer75,010-1234-5678,true
test76@example.com,1234,TEST76,Test Developer76,010-1234-5678,true
test77@example.com,1234,TEST77,Test Developer77,010-1234-5678,true
test78@example.com,1234,TEST78,Test Developer78,010-1234-5678,true
test79@example.com,1234,TEST79,Test Developer79,010-1234-5678,true
test80@example.com,1234,TEST80,Test Developer80,010-1234-5678,true
test81@example.com,1234,TEST81,Test Developer81,010-1234-5678,true
test82@example.com,1234,TEST82,Test Developer82,010-1234-5678,true
test83@example.com,1234,TEST83,Test Developer83,010-1234-5678,true
test84@example.com,1234,TEST84,Test Developer84,010-1234-5678,true
test85@example.com,1234,TEST85,Test Developer85,010-1234-5678,true
test86@example.com,1234,TEST86,Test Developer86,010-1234-5678,true
test87@example.com,1234,TEST87,Test Developer87,010-1234-5678,true
test88@example.com,1234,TEST88,Test Developer88,010-1234-5678,true
test89@example.com,1234,TEST89,Test Developer89,010-1234-5678,true
test90@example.com,1234,TEST90,Test Developer90,010-1234-5678,true
test91@example.com,1234,TEST91,Test Developer91,010-1234-5678,true
test92@example.com,1234,TEST92,Test Developer92,010-1234-5678,true
test93@example.com,1234,TEST93,Test Developer93,010-1234-5678,true
test94@example.com,1234,TEST94,Test Developer94,010-1234-5678,true
test95@example.com,1234,TEST95,Test Developer95,010-1234-5678,true
test96@example.com,1234,TEST96,Test Developer96,010-1234-5678,true
test97@example.com,1234,TEST97,Test Developer97,010-1234-5678,true
test98@example.com,1234,TEST98,Test Developer98,010-1234-5678,true
test99@example.com,1234,TEST99,Test Developer99,010-1234-5678,true
test100@example.com,1234,TEST100,Test Developer100,010-1234-5678,true

 


Config 설정

User Defined Variables
  • Add → Config Element → User Defined Variables
  • 준비한 유저 정보를 이용하기 위해 우선 Test Plan에 User Defined Variables를 추가하고 변수로 선언

 

CSV Data Set Config
  • Add → Config Element → CSV Data Set Config
  • FileName에 미리 만들어둔 테스트 계정 텍스트파일 추가
  • Variable Names는 User Defined Variables에 선언한 변수 이름과 Delimiter은 ","로 설정

 

HTTP Request Defaults
  • Add → Config Element → HTTP Request Defaults
  • 테스트 작성의 편리를 위해 HTTP Request에 공통적으로 들어가는 부분을 작성

 

HTTP Header Manager
  • Add → Config Element → HTTP Header Manager
  • Header에 공통적으로 들어가는 부분을 작성
  • 로그인 유저의 JWT토큰을 요청 헤더에 넣어주기 위해 사진과 같이 작성
  • ContentType은 JSON형식이라 작성

 

Config 설정 완료


회원 가입 API 작성
  • HTTP Method는 POST 방식으로 회원가입 API 호출
  • Server Name or IP와 Port Number는 HTTP Request Default에서 설정했기 때문에 작성하지 않음

 

Summary Report 확인
  • 100% 성공

 

Database 확인
  • 정상적으로 insert 완료


로그인 API 추가

 

JWT 토큰 추출
  • 로그인 Request 마우스 우 클릭 → Add → Post Processors → Regular Expression Extractor 추가
  • Regular Expression Extractor을 이용해 토큰을 추출
  • Response Header에 Authorization을 추출하여 JwtToken 이름으로 저장
  • 아래와 작성 시 HTTP Header Manager에서 설정한 것 처럼 모든 요청에 추출한 토큰값 추가

  • Name of created variable : JwtToken
    • 이 필드는 추출된 값을 저장할 변수의 이름을 지정
    • 여기서 JwtToken으로 지정하면, 추출된 JWT 토큰 값이 ${JwtToken} 변수에 저장되며, 이 변수는 JMeter의 후속 요청에서 사용 가능
  • Regular Expression: Authorization : (Bearer .+)
    • 이 필드는 JMeter가 응답에서 값을 추출하기 위해 사용할 정규 표현식을 지정
    • Authorization: (Bearer .+)는 응답에서 Authorization: Bearer로 시작하는 문자열을 찾아서 캡처 그룹으로 지정
    • 분석
      • Authorization: → 정규식에서 이 문자열을 그대로 찾음
      • (Bearer .+) → 괄호 안의 부분은 캡처 그룹으로, Bearer로 시작하고 그 뒤에 오는 모든 문자를 추출
        → 이 캡처된  값이 JwtToken 변수에 저장
  • Template ($i$ where i is capturing group number, start at 1): $1$
    • 이 필드는 정규식의 어떤 캡처 그룹을 사용할지 지정
    • $1$는 첫 번째 캡처 그룹(즉, Bearer .+로 매칭된 부분)을 추출하여 지정된 변수(JwtToken)에 저장
    • Ex) 만약 정규식이 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9와 매칭되면,
      $1$은 Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9을 나타내며, 이 값이 JwtToken 변수에 저장
  • Match No. (0 for Random): 1
    • 이 필드는 정규식과 매칭된 값 중 몇 번째 매치를 추출할지 지정
    • 1로 설정하면 첫 번째 매칭된 값을 추출
      만약 응답에서 정규식과 매칭되는 값이 여러 개 있을 경우, 그 중 첫 번째 값을 사용
    • 기타
      • 0으로 설정하면 랜덤으로 매칭된 값 중 하나를 선택
      • -1로 설정하면 모든 매칭된 값을 추출하여 변수명_1, 변수명_2, ... 형태로 저장
실행 결과


 

위시리스트 API 호출
  • 위시리스트는 로그인한 회원만 사용이 가능하기 때문에 위시리스트 등록 API를 호출하여, Response Header에서 JWT 토큰을 추출하고 Request Header에 추가한 뒤 API가 정상 호출 되는지 확인

 

Summary Report

 

Database
  • 정상적으로 insert 확인

로그인하여 Response Header에서 JWT 토큰을 추출하는 것이기 때문에
로그인 API를 회원 가입 API처럼 Disable을 하게 되면 JWT 토큰을 추출하지 못하여 에러 발생

주문 API 호출
  • 주문 시 eventStock을 가진 게임의 경우 원래 가격의 20% 할인
  • gameId 1번의 재고 : 50개
  • gameId 2번의 재고 : 200개
  • gameId 13번의 재고 : 30개
  • 총 100명의 회원이 아래와 같이 주문을 하게 될 경우
    • 1번 게임 재고 0개 / 50명 회원만 할인 적용
    • 2번 게임 재고 100개 / 100명 회원 모두 할인 적용
    • 13번 게임 재고 0개 / 30명의 회원만 할인 적용

 

주문 API 호출 후 결과

 

  • Summary Report : 성공률 100%

 

  • Database : Game Table

 

  • Database : Orders Table

 

  • 예상대로라면 Game Table에서 game_id 2번의 eventStock의 개수가 100개
  • Order Table도 아래와 같은 결과였어야 함
    • order_id 1 ~ 30 = 921,819
    • order_id 31 ~ 50 = 1,121,819
    • order_id 51 ~ 100 = 1,126,219

해당 문제는 동시다발적인 요청에 의해 동시성 문제가 발생한 것으로, Lock에 대한 개념을 공부한 뒤 적용해야할 문제임

어찌됐든 JMeter에서 JWT 토큰을 헤더에 추가한 뒤 다른 API들을 호출하는 것은 성공

 

'Tools' 카테고리의 다른 글

[JMeter] JMeter를 이용한 대용량 트래픽 측정  (0) 2024.09.18
[JMeter] JMeter 개념, 사용 방법  (0) 2024.09.04