首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >yii2从日志记录中排除变量

yii2从日志记录中排除变量
EN

Stack Overflow用户
提问于 2018-02-12 15:58:20
回答 2查看 1K关注 0票数 0

我需要为yii2日志创建路径。这个路径应该避免记录诸如密码等变量。根据文档(yii\log\Target),为了排除变量,我需要配置logVars。

在配置中:

代码语言:javascript
运行
复制
 'targets' => [
            [
                'class' => yii\log\FileTarget::className(),
                'levels' => ['error', 'warning'],
                'maxLogFiles' => 1000,
                'maxFileSize' => 102400,
                'logVars' => '!_POST[LoginForm[password]]',
            ],

但是LoginForm密码仍然出现在日志文件中。如何正确配置logVars。

我试过了!LoginForm.password,!_POST.LoginForm.password

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-12 19:14:29

我编写的代码也是为了同样的目的--也许你会发现它很有用。

在选定的目标类中重写getContextMessage(),如:

代码语言:javascript
运行
复制
<?php

namespace your\namespace\here;

use yii\helpers\ArrayHelper;

class FileTarget extends \yii\log\FileTarget
{
    protected function getContextMessage()
    {
        $context = ArrayHelper::filter($GLOBALS, $this->logVars);
        $result = [];
        foreach ($context as $key => $value) {
            if (\is_string($value) && stripos($key, 'password') !== false) {
                $result[] = "\${$key} = '** PASSWORD HIDDEN **'";
            } else {
                $result[] = "\${$key} = " . \your\namespace\here\LogVarDumper::dumpAsString($value);
            }
        }
        return implode("\n\n", $result);
    }
}

VarDumper重写LogVarDumper类(上面使用):

代码语言:javascript
运行
复制
<?php

namespace your\namespace\here;

use yii\base\InvalidValueException;

/**
 * Class LogVarDumper
 * Extended to handle logs password fields darkening.
 */
class LogVarDumper extends \yii\helpers\VarDumper
{
    private static $_objects;
    private static $_output;
    private static $_depth;

    public static function dumpAsString($var, $depth = 10, $highlight = false)
    {
        self::$_output = '';
        self::$_objects = [];
        self::$_depth = $depth;
        self::dumpInternal($var, 0);
        if ($highlight) {
            $result = highlight_string("<?php\n" . self::$_output, true);
            self::$_output = preg_replace('/&lt;\\?php<br \\/>/', '', $result, 1);
        }

        return self::$_output;
    }

    /**
     * @param mixed $var variable to be dumped
     * @param int $level depth level
     * @param bool $passwordKey whether password related key was present in previous iteration
     */
    private static function dumpInternal($var, $level, $passwordKey = false)
    {
        switch (gettype($var)) {
            case 'boolean':
                self::$_output .= $var ? 'true' : 'false';
                break;
            case 'integer':
                self::$_output .= "$var";
                break;
            case 'double':
                self::$_output .= "$var";
                break;
            case 'string':
                if ($passwordKey) {
                    self::$_output .= "'** PASSWORD HIDDEN **'";
                } else {
                    self::$_output .= "'" . addslashes($var) . "'";
                }
                break;
            case 'resource':
                self::$_output .= '{resource}';
                break;
            case 'NULL':
                self::$_output .= 'null';
                break;
            case 'unknown type':
                self::$_output .= '{unknown}';
                break;
            case 'array':
                if (self::$_depth <= $level) {
                    self::$_output .= '[...]';
                } elseif (empty($var)) {
                    self::$_output .= '[]';
                } else {
                    $keys = array_keys($var);
                    $spaces = str_repeat(' ', $level * 4);
                    self::$_output .= '[';
                    foreach ($keys as $key) {
                        self::$_output .= "\n" . $spaces . '    ';
                        self::dumpInternal($key, 0);
                        self::$_output .= ' => ';
                        self::dumpInternal($var[$key], $level + 1, strpos(strtolower($key), 'password') !== false);
                    }
                    self::$_output .= "\n" . $spaces . ']';
                }
                break;
            case 'object':
                if (($id = array_search($var, self::$_objects, true)) !== false) {
                    self::$_output .= get_class($var) . '#' . ($id + 1) . '(...)';
                } elseif (self::$_depth <= $level) {
                    self::$_output .= get_class($var) . '(...)';
                } else {
                    $id = array_push(self::$_objects, $var);
                    $className = get_class($var);
                    $spaces = str_repeat(' ', $level * 4);
                    self::$_output .= "$className#$id\n" . $spaces . '(';
                    if ('__PHP_Incomplete_Class' !== get_class($var) && method_exists($var, '__debugInfo')) {
                        $dumpValues = $var->__debugInfo();
                        if (!is_array($dumpValues)) {
                            throw new InvalidValueException('__debuginfo() must return an array');
                        }
                    } else {
                        $dumpValues = (array) $var;
                    }
                    foreach ($dumpValues as $key => $value) {
                        $keyDisplay = strtr(trim($key), "\0", ':');
                        self::$_output .= "\n" . $spaces . "    [$keyDisplay] => ";
                        self::dumpInternal($value, $level + 1);
                    }
                    self::$_output .= "\n" . $spaces . ')';
                }
                break;
        }
    }
}

并在日志配置中使用your\namespace\here\FileTarget。您可以使用所选目标的所有可用属性,现在所有以其名称包含password的字段(字段值为string )都将记录** PASSWORD HIDDEN **而不是实际密码。

票数 5
EN

Stack Overflow用户

发布于 2018-02-12 17:00:24

默认目标组件只过滤一个级别的键。

因此,您可以执行!_POST.LoginForm来过滤LoginForm的所有字段,但不能过滤特定的字段。

代码语言:javascript
运行
复制
'logVars' = [
    '_GET',
    '_POST',
    '_FILES',
    '_COOKIE',
    '_SESSION',
    '_SERVER',
    '!_POST.LoginForm'
    ],

将为您提供所有默认日志记录,但在LoginForm中发布的所有字段除外。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48750497

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档