New Relic Now Start training on Intelligent Observability February 25th.
Save your seat.
CDPのスクリプトログ

初めてページにアクセスすると、ほぼ確実にCookieモーダルがポップアップし、そのサイトのCookieを受け入れるか、拒否するか、または管理するかを選択する必要があります。もしくは、少なくともモーダルを閉じる前に、Cookieの使用について通知されます。ユーザーがどちらを選択したのかは、通常Cookieを使用して記録されており、次回以降のページ読み込み時にCookieが読み取られることで、モーダルが再び表示されないようにします。

Scripted Browser Monitorを実行する度に、Cookieが設定されていない新しいブラウザセッションが開始されるため、最初のページ読み込み時にCookieのモーダルが必ず表示されます。同意する、同意しない、閉じるといったボタンを見つけて、いずれかをクリックするスクリプトを作成する代わりに、同意する/同意しないを示すCookieを最初に設定することで、モーダルを表示させずにセッションを開始することができます。

もう一つの使用例は、多要素認証(MFA)が必要なログインの際にCookieを設定することです。ユーザーが既に認証されたと定義するCookieを使用できれば、Scripted Browser Monitorでログインや2段階目の認証をバイパスすることができます。これにより、MFAで使用されるSMSコード、電子メール、アプリなどの処理を設定およびスクリプト化する必要がなくなります。

$webDriver.manage()を使用したCookie設定

Scripted Browser MonitorでCookieを設定する標準的な方法は、$webDriver.manage()関数から利用できるaddCookie()を使用することです。

このメソッドは、ブラウザ内で開かれているコンテンツの現在のドメインに対してCookieを設定します。Cookie名とその値だけを指定すればよいのですが、トップレベルドメインに対してCookieを設定したい場合は、オプションでドメインを指定することもできます。例えば、現在、www.example.comを閲覧していて、Cookieをsite2.example.comにも使用したい場合は、ドメインをexample.comと指定できます。

この方法を使ってCookieを設定するには、既に最初のページにいるか、あるいは画像やスタイルシートのようなリソースを同じドメインから読み込んで、目的のCookieを設定する必要があります。理想的には、コンテンツを読み込む前に、最初にCookieを設定できることが望ましいです。これにより、最初のページを望み通りの状態にできます。特に認証Cookieが設定されていない場合に、別のドメインにリダイレクトされるようなログインをバイパスしようとする場合に重要です。

ブラウザの開発者ツールを使用すれば、任意のドメインのCookieを作成して設定することができます。では、モニター内から開発者ツールにアクセスできたらどうでしょうか?

Chrome DevTools Protocol

Chrome DevTools ProtocolやCDP(Firefoxでも利用可能)は、開発者ツールのUIにアクセスすることなく、開発者ツール内で利用可能な値の取得・設定や特定のアクションを実行する方法を提供します。このプロトコルは、さまざまなドメインを通じてアクセスできる多くのメソッド、イベント、タイプを提供しています。Network Domainには、Cookieを設定するためのメソッドがあり、Network.setCookieという名前で利用できます。

では、このメソッドが使えることがわかったところで、monitor scriptではどのように実装すればよいでしょうか?

createCDPConnection

Selenium WebDriverは、createCDPConnection()関数を提供しており、ページへの接続を作成できます。この接続は、オブジェクト内で返され、execute()関数を使用してCDPで利用可能なさまざまなメソッドを呼び出すことができます。

// CDPを使用してChrome Dev Toolsへの接続を作成
const CDP = await $webDriver.createCDPConnection('page');

// Cookieを設定
CDP.execute('Network.setCookie', {
    name: $secure.MANAGE_COOKIES_NAME,
    value: $secure.MANAGE_COOKIES_VALUE,
    domain: 'newrelic.com'
});


// 最初のページを取得 -
// Cookieが設定済みでリクエストで送信
await $webDriver.get('https://www.newrelic.com/');

// CDP接続のWebSocketを閉じる
CDP._wsConnection.close();

execute()関数は次の2つの引数を取ります。CDPメソッド名(この場合はNetwork.setCookie)と、指定したメソッドに設定するパラメータを含むオブジェクトです。上の例では、Cookieの名前、値、ドメインのみを設定しています。また、名前と値の両方で、 安全な認証情報を使用している点に注目してください。これは機密情報を安全に保つだけでなく、複数のモニターで値を使用するときに値の更新を管理する便利な方法でもあります。

ページが取得され、CDP接続が完了したら、接続を閉じる必要があります。接続が閉じられていない場合、Synthetic Checkは完了できず、最終的にはタイムアウトによりチェックが失敗します(パブリックロケーションから実行されるチェックのタイムアウトは3分です)。CDPオブジェクトには独自のclose()関数がないため、上記の例の末尾のように、WebSocket接続オブジェクト_wsConnection内の関数にアクセスする必要があります。

オプション:メッセージをリッスンする

CDP接続はWebSocketであるため、実行されるメソッドからメッセージは直接出力されませんが、代わりに、リッスンできるメッセージとして受信されます。以下では、返されるメッセージのCDP接続のWebSocketに対してイベントリスナー(4〜7行目)を追加してサンプルスクリプトを拡張し、メッセージをコンソールに出力します。これはオプションであり、デバッグ目的でのみ必要となりますが、Cookieが正常に設定されたかどうかを確認できます。

// CDPを使用してChrome Dev Toolsへの接続を作成
const CDP = await $webDriver.createCDPConnection('page');

// --- オプション --- 
// CDPから返されるメッセージにリスナーを設定
CDP._wsConnection.addEventListener("message",(event) => {
  console.log("Messagefrom CDP: ", event.data);
});

// Cookieを設定
CDP.execute('Network.setCookie',{
    name: $secure.MANAGE_COOKIES_NAME,
    value: $secure.MANAGE_COOKIES_VALUE,
    domain: 'newrelic.com'
});


// 最初のページを取得 -
// Cookieが設定済みでリクエストで送信
await $webDriver.get('https://www.newrelic.com/');

// CDP接続のWebSocketを閉じる
CDP._wsConnection.close();
New Relic Browser Monitoring

CDPはFirefoxでサポートされているため、新しいFirefoxブラウザオプションを利用するScripted Browser MonitorでCookieを設定するオプションがあります。

重要ポイント

Scripted Browser MonitorでのCookieを活用による、よりスムーズで効率的な運用と管理に関する考察を以下に示します:

  • Cookieを使用することで、特定のアクションをスクリプト化する必要がなくなり、Scripted Browser Monitorをシンプルにできます。
  • Cookieを活用することで、Cookieモーダルの承認/閉じる操作や、ログインに必要なMFA(多要素認証)の処理をスクリプト化する必要性を回避できます。
  • Cookieの設定には、addCookie()またはCDP Network.setCookieのいずれか、用途に応じて適した方法を使用します。
  • パスワードやCookieの値だけでなく、ユーザー名やCookie名にも安全な認証情報を使用することで、複数のスクリプトでの更新作業を避けることができます。
  • CDPと多様なメソッドにアクセスできることから、オブザーバビリティのニーズに応じてこれらのセッションから他のデータを取得することも可能です。