ワンタイムパスワードを使った認証の画面の性能テストをする際に、受信したメールからワンタイムパスワードを取得して認証するという操作が必要です。今回はメールからワンタイムパスワードを取得して、取得したワンタイムパスワードを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
というメールが届くという前提でコードを書いています。
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コードの配置
JmeterのBeanShellSamplerの作成
JmeterでBeanShellSamplerを作成して以下のようにスクリプトを書きます。
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の設定
テンプレートリテラル${}で変数を囲ってあげると、当該コンポーネントより前に宣言された変数の値を取り出すことができます。
メールの作成
自分から自分あてにワンタイムパスワードのメールを作成します。
Jmeterの実行
上のスタートボタンを実行してView Results Treeから実行結果を見てみます。
otpにメールから取得した値が設定できたことが確認できました。
参考
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/