다음을 통해 공유


사용자 지정 플러그 인 만들기

이 문서에서는 개발자 프록시에 대한 사용자 지정 플러그 인을 만드는 방법을 알아봅니다. 개발자 프록시용 플러그 인을 만들어 해당 기능을 확장하고 필요에 맞게 사용자 지정 기능을 추가할 수 있습니다.

필수 조건

사용자 지정 플러그 인 만들기를 시작하기 전에 다음 필수 구성 요소가 있는지 확인합니다.

새 플러그 인 만들기

다음 단계에 따라 새 프로젝트를 만듭니다.

  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 추가하여 빌드 출력에서 종속성 DLL을 PackageReference 제외합니다DevProxyCustomPlugin.csproj.

    <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
    

예제 플러그 인은 필요한 권한 부여 헤더에 대해 일치하는 모든 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