コンテンツにスキップ

アウトバウンドワーカー

アウトバウンドワーカーは、顧客のワーカーとパブリックインターネットの間に位置します。これにより、ユーザーワーカーからのすべての出力fetch()リクエストを可視化できます。

アウトバウンドワーカーの図情報

一般的なユースケース

アウトバウンドワーカーは以下の目的で使用できます:

  • 悪意のあるドメインや使用パターンを特定するために、すべてのサブリクエストをログに記録する。
  • ユーザーワーカーによってリクエストされたホスト名の作成、許可、またはブロックリストを作成する。
  • エンド開発者が資格情報を設定する必要なく、背後でAPIへの認証を構成する。

アウトバウンドワーカーの使用

アウトバウンドワーカーを使用するには:

  1. アウトバウンドワーカーとして機能することを意図したワーカーを作成します。
  2. アウトバウンドワーカーは、プロジェクトのwrangler.tomldispatch namespacesバインディングでオプションのパラメータとして指定できます。オプションで、動的ディスパッチワーカーからアウトバウンドワーカーにデータを渡すために、変数名をparametersの下に指定できます。

wrangler@3.3.0以降がインストールされていることを確認してください

[[dispatch_namespaces]]
binding = "dispatcher"
namespace = "<NAMESPACE_NAME>"
outbound = {service = "<SERVICE_NAME>", parameters = ["params_object"]}
  1. 動的ディスパッチワーカーを編集して、アウトバウンドワーカーを呼び出し、dispatcher.get()で渡す変数を宣言します。
export default {
async fetch(request, env) {
try {
// URLを解析し、サブドメインを読み取る
let workerName = new URL(request.url).host.split('.')[0];
let context_from_dispatcher = {
'customer_name': workerName,
'url': request.url,
}
let userWorker = env.dispatcher.get(
workerName,
{},
{// アウトバウンド引数。オブジェクト名はバインディングのparametersと一致する必要があります
outbound: {
params_object: context_from_dispatcher,
}
}
);
return await userWorker.fetch(request);
} catch (e) {
if (e.message.startsWith('Worker not found')) {
// ディスパッチネームスペースに存在しないワーカーを取得しようとしました
return new Response('', { status: 404 });
}
return new Response(e.message, { status: 500 });
}
}
}
  1. アウトバウンドワーカーは、ユーザーワーカーからのすべてのfetch()リクエストで呼び出されます。ユーザーワーカーは、アウトバウンドワーカーでFetchEventをトリガーします。バインディングで宣言された変数は、env.<VAR_NAME>を通じてアウトバウンドワーカーでアクセスできます。

以下は、ユーザーワーカーからのフェッチリクエストをログに記録し、フェッチリクエストがapi.example.comに一致する場合にJWTを作成するアウトバウンドワーカーの例です。

export default {
// ディスパッチされたワーカーがサブリクエストを行うときにこのイベントが発火します
async fetch(request, env, ctx) {
// envには`dispatcher.get()`で設定した値が含まれています
const customer_name = env.customer_name;
const original_url = env.url;
// リクエストをログに記録
ctx.waitUntil(fetch(
'https://logs.example.com',
{
method: 'POST',
body: JSON.stringify({
customer_name,
original_url,
}),
},
));
const url = new URL(original_url);
if (url.host === 'api.example.com') {
// APIへの事前認証リクエスト
const jwt = make_jwt_for_customer(customer_name);
let headers = new Headers(request.headers);
headers.set('Authorization', `Bearer ${jwt}`);
// 既存のボディを使用して新しいヘッダーを設定するためにリクエストをクローン
let new_request = new Request(request, {headers});
return fetch(new_request)
}
return fetch(request)
}
};