allejo/php-vcr-sanitizer

通过排除API密钥、密码和凭据,将隐私引入php-vcr的录制中

v1.1.0 2023-02-10 06:19 UTC

This package is auto-updated.

Last update: 2024-09-23 04:39:26 UTC


README

Packagist Tested with php-vcr v1.4+ Unit Tests GitHub license

php-vcr 是一个用于记录和重放外出请求的工具,然而它已经将“隐私感知”标记为“即将推出”很长时间了。每当我测试我的API时,记录中经常会包含一些敏感信息,如密钥或密码。到目前为止,我一直在使用一个单独的脚本,在提交到版本控制之前始终删除敏感数据。

我不愿意总是清理数据,因此这是一个快速且简单的解决方案,直到php-vcr官方支持“私人”录制。

目录

安装

通过 Composer 安装此包。

composer require --dev allejo/php-vcr-sanitizer

使用

在您的VCR实例开启后,调用 VCRCleaner::enable() 并传递您不希望在固定文件中记录的任何URL参数或头部。

VCR::turnOn();
VCR::insertCassette('...');

VCRCleaner::enable(array(
   'request' => array(
       'ignoreHostname' => false,
       'ignoreQueryFields' => array(
           'apiKey',
       ),
       'ignoreHeaders' => array(
           'X-Api-Key',
       ),
       'bodyScrubbers' => array(
           function($body) {
               return preg_replace('/<password.*?<\/password>/', 'hunter2', $body);
           }
       ),
       'postFieldScrubbers' => array(
           function(array $postFields) {
               $postFields['Secret'] = 'REDACTED';
               return $postFields;
           }
       ),
   ),
   'response' => array(
       'ignoreHeaders' => array('*'),
       'bodyScrubbers' => array(),
   ),
));

配置

此库允许您清理录制中的请求和响应部分,以确保只有非敏感数据写入您的磁带。您可以通过下面的配置选项定义此清理器的行为。

清理请求

  • request.ignoreHostname - 当设置为true时,请求中的URL内的主机名将在 url 字段中替换为 [],并且在头部中的 Host 将设置为null。
  • request.ignoreQueryFields - 定义您要完全从记录中删除的URL中的GET参数。
  • request.ignoreHeaders - 定义在记录中会自动设置为null的头部。在数组中使用星号(例如 *)可以用来从请求中删除所有头部。
  • request.bodyScrubbers - 一个回调函数数组,这些回调函数将请求正文作为字符串提供。每个回调 必须 返回修改后的正文。回调按数组中出现的顺序依次调用,一个回调的值会传递给下一个。
  • request.postFieldScrubbers - 一个回调函数数组,这些回调函数将请求POST字段作为数组提供。每个回调 必须 返回修改后的POST字段数组。回调按数组中出现的顺序依次调用,一个回调的值会传递给下一个。

清理响应

php-vcr库官方不支持修改其响应,因此此库使用反射来修改响应的内容。虽然此功能由 本项目 正式支持,但如果由于php-vcr内部更改导致此功能出现问题,请耐心等待。

  • response.ignoreHeaders - 与 request.ignoreHeaders 相同,但用于响应体。
  • response.bodyScrubbers - 与 request.bodyScrubbers 相同,但用于响应体。

禁用清理器

为什么没有 VCRCleaner::disable()?没有简单且非侵入式的方法来恢复VCR到其原始状态。可能还是直接为某些批次的单元测试重新配置VCR更简单。

清理工作原理

当VCR寻找回放记录时,VCRCleaner使用修改后的“匹配器”来检查除了你标记为敏感的字段之外的所有内容。

主机名

如果你的URL端点的hostname是敏感的且不应被记录,你可以让sanitizer忽略hostname,它们将在url字段中被替换为[],并且host头将被设置为null。

-
    request:
        method: GET
        url: 'https://[]/search'
        headers:
            Host: null
            X-Type: application/vcr
    response:
        status:
            http_version: '1.1'
            code: '404'
            message: 'Not Found'
        headers: ~
        body: "...response body..."

头部

假设你将X-Api-Key头设置为SuperToast。在你的记录中,你指定的头将被保存为null。

-
    request:
        method: GET
        url: 'https://www.example.com/search'
        headers:
            Host: www.example.com
            X-Api-Key: null
            X-Type: application/vcr
    response:
        status:
            http_version: '1.1'
            code: '404'
            message: 'Not Found'
        headers: ~
        body: "...response body..."

URL参数

注意在记录中apiKey=yourSecretApiKey已被移除。在你的VCR回放期间,它将寻找没有apiKey参数的匹配请求。

# Your cURL call to: https://www.example.com/search?q=keyword&apiKey=yourSecretApiKey
# gets recorded like so,
-
    request:
        method: GET
        url: 'https://www.example.com/search?q=keyword'
        headers:
            Host: www.example.com
    response:
        status:
            http_version: '1.1'
            code: '404'
            message: 'Not Found'
        headers: ~
        body: "...response body..."

正文内容

与忽略头或URL参数不同,从请求和响应体中清除信息使用了回调函数数组。每个函数的结果会传递给下一个函数。

注意请求体中的password=hunter2已被移除。回调函数将body作为字符串参数,必须返回修改后的结果。

VCRCleaner::enable(array(
    'request' => array(
        'bodyScrubbers' => array(
            function ($body) {
                $parameters = array();

                parse_str($body, $parameters);
                unset($parameters['password']);

                return http_build_query($parameters);
            },
        ),
    ),
));
# You POST request to `https://www.example.com/search` with a body of
# `username=AzureDiamond&password=hunter2` gets recorded like so,
-
    request:
        method: POST
        url: 'https://www.example.com/search'
        headers:
            Host: www.example.com
        body: 'username=AzureDiamond'
    response:
        status:
            http_version: '1.1'
            code: '404'
            message: 'Not Found'
        headers: ~
        body: '...response body...'

POST字段内容

在发送POST请求时,你的VCR有时会记录post_fields参数中的数据而不是body;例如,当在cURL中使用CURLOPT_POSTFIELDS且没有将CURLOPT_POST设置为true时。在这些情况下,此选项可用于清理敏感内容。注意,与body字段不同,post_fields是一个数组。

VCRCleaner::enable(array(
    'request' => array(
        'postFieldScrubber' => array(
            function (array $postFields) {
                $postFields['Secret_Key'] = '';
                return $postFields;
            },
        ),
    ),
));
# You POST request to `https://www.example.com/search` with a post field of
# `['data'=> 'hello world', 'Secret_Key' => 'abc']` gets recorded like so,
-
    request:
        method: POST
        url: 'https://www.example.com/search'
        headers:
            Host: www.example.com
        post_fields:
            data: 'hello world'
            Secret_Key: ''
    response:
        status:
            http_version: '1.1'
            code: '404'
            message: 'Not Found'
        headers: ~
        body: '...response body...'

许可

MIT