2FA: two-factor authentication = 二要素認証/2要素認証
この記事では以下、2FAで記載する。
E2Eとセキュア問題
E2Eテストするサイトがログインが必要かつ2FAが必須というサイトが当たり前になりつつある。
で、E2Eテストするときにヘッドレスブラウザ上で当然ログインする必要があるわけなのだけど、2FAをどうすればいいかという問題がある。
公式ガイドの認証情報取り回し方法を見る
認証情報を全テストで共有する方法と、どう扱うかというガイドがある。
詳細は読んでもらうとして、ざっくり見ると
mkdir -p playwright/.auth echo "\nplaywright/.auth" >> .gitignore
まずこうして、センシティブ情報をコミットしないようにして、
const authFile = 'playwright/.auth/user.json'; await page.context().storageState({ path: authFile });
Playwrightで必要な操作を走らせたあとにファイルに書き出して、
{ name: 'chromium', use: { ...devices['Desktop Chrome'], // Use prepared auth state. storageState: 'playwright/.auth/user.json', }, }
あとはconfigに挿し込むとOKという具合。
でも 2023-02-26現在、2FAに関する記述はない
解決方法は2択
ランタイムでTOTP生成して解決する方法
こういった同じ問題に取り組んでいるブログがある。
- How To Test Your Web Applications Using Playwright and Support 2fa Tokens - I Like Kill Nerds
- How to Bypass TOTP-Based 2FA Login Flows With Playwright | Checkly blog
これらブログの内容は、普通に setup
処理として「シナリオ内でTOTPを生成して普通に2FA突破する」という方法。
わかる。
Pros
- 完全にprogrammaticallyに2FA突破してE2Eできる
- 2FAの動作自体をテストしたい場合はこの方法で完全に再現できる
Cons
- パスワードとTOTPのシークレットをenvなりsecretmanager的なセキュアな場所に置いておく必要がある
- TOTPのQRコードを1度生成済みだと無理(生成済みsecretを何回もREADできるサービスを自分は見たことがない)
- E2E用システムユーザーを用意できるのなら問題ない
1度だけ人力で2FAする
もう一つは自分で1回だけPlaywrightのheadedモード(実際にchromiumブラウザが起動する)で普通にログイン作業をして2FAを突破しておく、という方法。
例えば GitHubにログインする場合。
playwright codegen https://github.com/login --save-storage playwright/.auth/user.json
codegenモードで起動してポチポチログイン作業する。 --save-storage
しているのでセッションが書き出される。
ためしに確認のために --load-storage
すると、ちゃんとログイン後の画面になることがわかる。
playwright codegen https://github.com/login --load-storage playwright/.auth/user.json",
Pros
- ローカルでE2Eを走らせればOKというときにセットアップがラク
- セットアップスクリプトに組み込んでおけばいい
- ローカルの.envとかにパスワードとOTPシークレットを置かなくてよい
- 個人あるいは既存のすでにTOTP設定済みアカウントを使い回せる
- E2E用のシステムユーザーを用意できない場合でもなんとかなる
Cons
- 完全にprogrammaticallyではない
- CIで動かしたいときに面倒
- とはいえ
playwright/.auth/user.json
をセキュアに取り扱えばOK(TOTP生成の方式でも同じセンシティブ情報置き場問題はある)
- とはいえ
- 2FAの画面の2FAの実装自体をテストしたい場合はE2Eできてないのでダメ
どっちの作戦で行くかはケースバイケースだと思う。
どっちも認証情報は playwright/.auth/user.json
に置いてPlaywrightに食べさせるので、テスト対象や認証フローやセンシティブ情報の置き場所やセットアップのラクさで選べばいい気がしている。