当我调用 warning() 或 info() 时,如何防止帖子变量出现在 Yii2 日志中


How can I prevent post variables from appearing in the Yii2 log when I call warning() or info()?

我正在维护一个用 Yii2 构建的应用程序,我想使用 Yii::warning() 来编写日志消息。这很好,除非我在用户登录序列中记录事件。

用户名和密码作为 POST 变量发送。这些是敏感信息,不应在日志文件中捕获。

$errorno = ldap_errno($this->link);
$errorstr = ldap_err2str($errorno);
Yii::warning("LDAP error: $errorno: $errorstr");

上面的代码会导致出现一个日志警告,其中包含我的 ldap 错误消息,但该警告包含完整的堆栈跟踪和 POST 变量。

即使仅在 LDAP 连接出现问题时才写入警告,它也可能包含当时任何用户的凭据,从服务器管理员到 CEO。

如何在 Yii 中记录认证相关事件的警告,而无需获取 POST 字段的完整堆栈跟踪和转储?

您可以为每个日志目标配置将哪些 PHP 超全局变量导出到日志中。在您的配置文件中,例如:

'log' => [
    'traceLevel' => YII_DEBUG ? 3 : 0,
    'targets' => [
        [
            'class' => 'yii'log'FileTarget',
            'levels' => ['error', 'warning'],
            'logVars' => ['_GET', '_POST', '_FILES', '_COOKIE', '_SESSION', '_SERVER'],
        ],
    ],
],

上面的示例中显示了省略 logVars 属性时的默认设置等效项。

为了避免日志中的敏感数据泄漏,您可以简单地屏蔽日志文件中的任何变量,对于任何类型的级别,不仅仅是警告。

'log' => [
    'traceLevel' => YII_DEBUG ? 3 : 0,
    'targets' => [
        [
            'class' => 'yii'log'FileTarget',
            'levels' => ['error', 'warning'],
            'maskVars' => [
                // current vars in vendor/yiisoft/yii2/log/Target.php::$maskVars
                '_SERVER.HTTP_AUTHORIZATION',
                '_SERVER.PHP_AUTH_USER',
                '_SERVER.PHP_AUTH_PW',
                // Filter and mask any POST vars. Examples:  
                //      '_POST.add_var_name_here'
                //      '_POST.your_form_name.your_field_name'
                // see: vendor/yiisoft/yii2/log/Target.php::$maskVars
                // see: vendor/yiisoft/yii2/log/Target.php::getContextMessage()
                '_POST.LoginForm.email',
                '_POST.LoginForm.password',
            ],
        ],
    ],
],

现在练习,如何确定和设置掩码变量。假设您在日志中看到类似以下内容:

$_POST = [
    'LoginForm' => [
        'email' => 'example@example.com'
        'password' => 'mysecretpassword'
    ]
]

要屏蔽电子邮件和密码,您只需要将'_POST.LoginForm.email''_POST.LoginForm.email'添加到maskVars配置中。

PS:通过这种方式,你可以屏蔽全局变量中的任何合理变量:

'_SERVER.add_var_name_here',
'_FILES.add_var_name_here',
'_COOKIE.add_var_name_here',
'_SESSION.add_var_name_here',
'_POST.add_var_name_here',
'_GET.add_var_name_here',