1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

メールOTPを取得してjmeterで負荷をかける

Last updated at Posted at 2025-03-28

ワンタイムパスワードを使った認証の画面の性能テストをする際に、受信したメールからワンタイムパスワードを取得して認証するという操作が必要です。今回はメールからワンタイムパスワードを取得して、取得したワンタイムパスワードをhttpのbodyデータに乗せるところまでを検証したのでその記録となります。

取得方法

gmailの内容を取得する方法は私が観測した限り以下の2つがあります。
・OAuthを使ったgmail APIを使って取得
・IMAPサーバーから取得

今回はIMAPサーバーから取得で検証しました。
(OAuthを使ったgmail APIだと無料枠があるとはいえ従量課金になるので、また今度検証します。)

アプリパスワードの設定

下記を参考にアプリパスワードを設定します。
https://support.google.com/accounts/answer/185833

OTPを取得するpythonを作成

pythonの環境がない場合は構築します。
参考:https://qiita.com/million_hundred/items/3787f6c61a4fb38d6a89

OTPを取得するpythonコードを書きます。
件名:OTP
メール本文:Your OTP is 123456
というメールが届くという前提でコードを書いています。

python get_otp.py
import imaplib
import email 
from email.header import decode_header
import re

# メールサーバーの情報
username = "example@gmail.com"
password = "aplicationPassword"
mail_server = "imap.gmail.com"
try:
    # IMAPサーバーに接続
    mail = imaplib.IMAP4_SSL(mail_server)
    mail.login(username, password)
    mail.select("inbox")

    # 最新のメールを取得
    result, data = mail.search(None, 'SUBJECT "OTP"')
    mail_ids = data[0].split()

    if not mail_ids:
        print("OTPに関するメールが見つかりません")
    else:
        latest_email_id = mail_ids[-1]
        
        # メールの内容を取得
        result, msg_data = mail.fetch(latest_email_id, "(RFC822)")
        raw_email = msg_data[0][1]
        msg = email.message_from_bytes(raw_email)

        # 件名OTPを取得
        subject, encoding = decode_header(msg["Subject"])[0]
        if isinstance(subject, bytes):
            subject = subject.decode(encoding if encoding else "utf-8")

        # メール本文を取得
        if msg.is_multipart():
            for part in msg.walk():
                if part.get_content_type() == "text/plain":
                    body = part.get_payload(decode=True).decode("utf-8", errors="ignore")
                    break
        else:
            body = msg.get_payload(decode=True).decode("utf-8", errors="ignore")

        # メール本文から、Your OTP is 123456のような6桁のOTPコードを取得
        otp_match = re.search(r"Your OTP is (\d{6})", body)
        if otp_match:
            print( otp_match.group(1))
        else:
            print("OTPコードが見つかりません")

    mail.logout()

except imaplib.IMAP4.error as e:
    print("IMAPエラー:", e)
except Exception as e:
    print("エラーが発生しました:", e)

pythonコードの配置

get_opt.pyをjmeterのbin直下に置きます。
image.png

JmeterのBeanShellSamplerの作成

JmeterでBeanShellSamplerを作成して以下のようにスクリプトを書きます。

image.png

String command = "python get_otp.py";
Process proc = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String otp = reader.readLine(); 
vars.put("otp", otp); 
log.info("OTP: " + otp);

http request bodyの設定

image.png
テンプレートリテラル${}で変数を囲ってあげると、当該コンポーネントより前に宣言された変数の値を取り出すことができます。

メールの作成

自分から自分あてにワンタイムパスワードのメールを作成します。
image.png

Jmeterの実行

上のスタートボタンを実行してView Results Treeから実行結果を見てみます。
otpにメールから取得した値が設定できたことが確認できました。
image.png

参考

https://qiita.com/HirumaT/items/75b45e67f9b08bb9c2fa
https://www.skyarch.net/blog/apache-jmeter%E3%81%A8beanshell%E3%81%A7%E6%9F%94%E8%BB%9F%E3%81%AA%E8%B2%A0%E8%8D%B7%E3%83%86%E3%82%B9%E3%83%88%E3%82%92%E3%81%97%E3%82%88%E3%81%86%EF%BC%81/

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?