• 0
  • 0

系统安全日志记录

2019-07-07 864 0 admin 所属分类:PHP 记录

当一个系统比较庞大的时候,往往会有专门的人员负责后台的管理。这个时候我们需要设定权限访问,还有添加日志记录。方便系统管理员进行回溯查看。

我这边可以从全局跟局部来考虑。

全局考虑,针对用户的每一次访问,我们做一次记录。可以区分前台、后台和API模块。

局部考虑,针对一些比较重要的模块,我们可以手工调用记录,详细记录访问信息(请求参数)。

数据库表结构如下

CREATE TABLE `action_log` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `uid` int(10) unsigned NOT NULL COMMENT '用户UID 0表示游客访问',
  `action` varchar(255) NOT NULL COMMENT '行为名',
  `descrip` varchar(255) NOT NULL COMMENT '行为描述',
  `url` varchar(255) DEFAULT '' COMMENT '请求地址',
  `params` varchar(600) NOT NULL COMMENT '请求参数',
  `ip` varchar(23) NOT NULL COMMENT 'IP地址',
  `kind` tinyint(3) NOT NULL DEFAULT '0' COMMENT '类型 0 后台 1前台 2 api  -1未知',
  `created_at` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `uid` (`uid`) USING BTREE
)  COMMENT='操作日志记录表'

可以在请求入口处添加全局日志记录

//后台日志记录
C::t(PT_ACTION_LOG)->init();

重要操作添加局部日志记录

C::t(PT_ACTION_LOG)->add('行为','描述');

具体实现模型

class table_action_log extends discuz_table
{
    protected $_table = 'action_log';
    protected $_pk    = 'id';

    public function add($action='',$descrip='')
    {
        $data = [
            'uid'=>$this->getUID(),
            'action'=>$action,
            'descrip'=>$descrip,
            'params'=>$this->getParams(),
            'url' => $this->getUrl(),
            'ip'=>$this->getUserIp(),
            'kind'=>$this->getKind(),
            'created_at'=>TIMESTAMP,
        ];
        return $this->insert($data, true);
    }

    public function remove_all() {
        global $_G;
        if ($_G['uid']!=1) {
            $this->add('remove','非管理员不允许删除日志信息');
            json(['status'=>0,'msg'=>'非管理员不允许操作']);
        } else {
            $day = intval($_GET['day']);
            if (!$day) {
                DB::query("delete from pre_wukong_action_log where id>0");
            } else {
                $time = date('Y-m-d',TIMESTAMP) - ($day-1)*86400;
                DB::query("delete from pre_wukong_action_log where created_at<{$time}");
            }
            $this->add('remove','删除日志信息');
            json(['status'=>1]);
        }
    }

    //全局初始化 自动化记录日志
    public function init() {
        global $admin_rolelist,$mod,$ac,$_G;
        $action = $mod.'-'.$ac;
        $kind = $this->getKind();
        if ($kind==0) {
            $action = 'admin-'.$action;
        }
        $modname = $admin_rolelist[$mod]['name'];
        $actions = $admin_rolelist[$mod]['children'];
        foreach ($actions as $k => $v) {
            if ($v['name']==($mod.'-'.$ac)) {
                $actionname = $v['display_name'];
            }
        }

        if (!$modname){
            $modname = '未知';
        }
        if (!$actionname) {
            if ($ac=='getList') {
                $actionname = '获取列表';
            } else if ($ac=='add'){
                $actionname = '添加';
            } else {
                $actionname = '未知';
            }
        }
        if ($_G['uid']==1) {
            // debug($actionname);
        }
        $descrip = $modname.'-'.$actionname;
        $this->add($action,$descrip);
    }


    /*
    --------------------------------------------------------
     */
    
    // 获取记录类型
    protected function getKind() {
        // debug(PT_ENTER);
        if (strpos(PT_ENTER,':admin')!==false) {
            return 0;
        } else if (strpos(PT_ENTER,':api')!==false) {
            return 2;
        } else if (PT_ENTER=='wukong') {
            return 1;
        } else {
            return -1;
        }
    }

    // 获取用于IP地址
    protected function getUserIp() {
        global $ip;
        return $ip;
    }

    //获取用户主键ID
    protected function getUID() {
        global $_G;
        return $_G['uid'];
    }

    //取得请求的参数列表
    protected function getParams() {
        return json_encode($_GET);
    }


    protected function getUrl() {
        return getProtocol() . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
    }

}

相关公用函数

function is_HTTPS()
{
    //  $_SERVER['HTTPS'] === 1 ->Apache  $_SERVER['HTTPS'] === 'on' ->IIS  其他->443
    if ($_SERVER['HTTPS'] === 1 || $_SERVER['HTTPS'] === 'on' || $_SERVER['SERVER_PORT'] == 443) {
        return true;
    }
    return false;
}

function getProtocol()
{
    return is_HTTPS() ? 'https://' : 'http://';
}


返回顶部