次の方法で共有


カスタム プラグインを作成する

この記事では、開発プロキシ用のカスタム プラグインを作成する方法について説明します。 開発プロキシ用のプラグインを作成することで、その機能を拡張し、ニーズに合わせてカスタム機能を追加できます。

前提条件

カスタム プラグインの作成を開始する前に、次の前提条件があることを確認してください。

新しいプラグインを作成する

次の手順に従って新しいプロジェクトを作成します。

  1. dotnet new classlib コマンドを使用して、新しいクラス ライブラリ プロジェクトを作成します。

    dotnet new classlib -n MyCustomPlugin
    
  2. Visual Studio Code で新しく作成したプロジェクトを開きます。

    code MyCustomPlugin
    
  3. 開発プロキシ抽象化 DLL (dev-proxy-abstractions.dll) をプロジェクト フォルダーに追加します。

  4. プロジェクト dev-proxy-abstractions.dll ファイルへの参照としてDevProxyCustomPlugin.csprojを追加します。

    <ItemGroup>
      <Reference Include="dev-proxy-abstractions">
        <HintPath>.\dev-proxy-abstractions.dll</HintPath>
        <Private>false</Private>
        <ExcludeAssets>runtime</ExcludeAssets>
      </Reference>
    </ItemGroup>
    
  5. プロジェクトに必要な NuGet パッケージを追加します。

    dotnet add package Microsoft.Extensions.Configuration
    dotnet add package Microsoft.Extensions.Configuration.Binder
    dotnet add package Microsoft.Extensions.Logging.Abstractions
    dotnet add package Unobtanium.Web.Proxy
    
  6. ExcludeAssets ファイルのPackageReferenceごとにDevProxyCustomPlugin.csproj タグを追加して、依存関係 DLL をビルド出力から除外します。

    <ExcludeAssets>runtime</ExcludeAssets>
    
  7. BaseProxyPlugin インターフェイスを実装する新しいクラスを作成します。

    using Microsoft.DevProxy.Abstractions;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    
    namespace MyCustomPlugin;
    
    public class CatchApiCalls(IPluginEvents pluginEvents, IProxyContext context, ILogger logger, ISet<UrlToWatch> UrlsToWatch, IConfigurationSection? configSection = null) : BaseProxyPlugin(pluginEvents, context, logger, UrlsToWatch, configSection)
    {
      public override string Name => nameof(CatchApiCalls);
    
      public override async Task RegisterAsync()
      {
        await base.RegisterAsync();
    
        PluginEvents.BeforeRequest += BeforeRequestAsync;
      }
    
      private Task BeforeRequestAsync(object sender, ProxyRequestArgs e)
      {
        if (UrlsToWatch is null ||
          !e.HasRequestUrlMatch(UrlsToWatch))
        {
          // No match for the URL, so we don't need to do anything
          Logger.LogRequest("URL not matched", MessageType.Skipped, new LoggingContext(e.Session));
          return Task.CompletedTask;
        }
    
        var headers = e.Session.HttpClient.Request.Headers;
        var header = headers.Where(h => h.Name == "Authorization").FirstOrDefault();
        if (header is null)
        {
          Logger.LogRequest($"Does not contain the Authorization header", MessageType.Warning, new LoggingContext(e.Session));
          return Task.CompletedTask;
        }
    
        return Task.CompletedTask;
      }
    }
    
  8. プロジェクトをビルドする。

    dotnet build
    

カスタム プラグインを使用する

カスタム プラグインを使用するには、それを開発プロキシ構成ファイルに追加する必要があります。

  1. devproxyrc.json ファイルに新しいプラグイン構成を追加します。

    {
      "plugins": [{
        "name": "CatchApiCalls",
        "enabled": true,
        "pluginPath": "./bin/Debug/net8.0/MyCustomPlugin.dll",
      }]
    }
    
  2. 開発プロキシを実行します。

    devproxy
    

この例のプラグインは、必要な Authorization ヘッダーについて、一致するすべての URL をチェックします。 ヘッダーが存在しない場合は、警告メッセージが表示されます。

プラグインへのカスタム構成の追加 (省略可能)

カスタム構成を追加することで、プラグインのロジックを拡張できます。

  1. 新しい _configuration オブジェクトを追加し、 Register メソッドでバインドします。

    using Microsoft.DevProxy.Abstractions;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    
    namespace MyCustomPlugin;
    
    public class CatchApiCallsConfiguration
    {
      public string? RequiredHeader { get; set; }
    }
    
    public class CatchApiCalls(IPluginEvents pluginEvents, IProxyContext context, ILogger logger, ISet<UrlToWatch> UrlsToWatch, IConfigurationSection? configSection = null) : BaseProxyPlugin(pluginEvents, context, logger, UrlsToWatch, configSection)
    {
      public override string Name => nameof(CatchApiCalls);
    
      // Define you custom configuration
      private readonly CatchApiCallsConfiguration _configuration = new();
    
      public override async Task RegisterAsync()
      {
        await base.RegisterAsync();
    
        // Bind your plugin configuration
        configSection?.Bind(_configuration);
    
        // Register your event handlers
        PluginEvents.BeforeRequest += BeforeRequestAsync;
      }
    
      private Task BeforeRequestAsync(object sender, ProxyRequestArgs e)
      {
        if (UrlsToWatch is null ||
          !e.HasRequestUrlMatch(UrlsToWatch))
        {
          // No match for the URL, so we don't need to do anything
          Logger.LogRequest("URL not matched", MessageType.Skipped, new LoggingContext(e.Session));
          return Task.CompletedTask;
        }
    
        // Start using your custom configuration
        var requiredHeader = _configuration?.RequiredHeader ?? string.Empty;
        if (string.IsNullOrEmpty(requiredHeader))
        {
          // Required header is not set, so we don't need to do anything
          Logger.LogRequest("Required header not set", MessageType.Skipped, new LoggingContext(e.Session));
          return Task.CompletedTask;
        }
    
        var headers = e.Session.HttpClient.Request.Headers;
        var header = headers.Where(h => h.Name == requiredHeader).FirstOrDefault();
        if (header is null)
        {
          Logger.LogRequest($"Does not contain the {requiredHeader} header", MessageType.Warning, new LoggingContext(e.Session));
          return Task.CompletedTask;
        }
    
        return Task.CompletedTask;
      }
    }
    
  2. プロジェクトをビルドする。

    dotnet build
    
  3. devproxyrc.json ファイルを更新して、新しい構成を含めます。

    {
      "plugins": [{
        "name": "CatchApiCalls",
        "enabled": true,
        "pluginPath": "./bin/Debug/net8.0/MyCustomPlugin.dll",
        "configSection": "catchApiCalls"
      }],
      "catchApiCalls": {
        "requiredHeader": "Authorization" // Example configuration
      }
    }
    
  4. 開発プロキシを実行します。

    devproxy