如何在Yii2中安全地使用客户端定义的查询字符串参数生成ActiveQuery?

时间:2018-10-08 17:51:10

标签: php yii2 query-string sql-injection

是否有一种安全的方法可以为带有查询字符串参数的 Yii2 ORM 生成条件子句? 例如,我们需要一些食品的列表,并按其属性进行过滤:

GET /food/?weight[>]=1000&calories=[<]=200

产品有很多不同的属性:重量,卡路里,数量,价格。

我希望可以编写类似(简化代码)的内容:

 $query = new \yii\db\Query();
 foreach ($_GET as $parameter => $condition){
    foreach ($condition as $operator => $value){
        $query->where(new SimpleCondition($parameter, $operator, $value));
    }
 }

但是我怀疑,这种方法是安全

因此,有三个问题:

  1. 如何从url安全地定义属性?在ActiveQuery::where子句中使用之前,我们可以对查询字符串参数 names (不是 values )进行消毒吗?
  2. 如何正确定义IN, AND, OR, >, <, >=, <=, etc.之类的运算符?
  3. 是否有任何本机Yii2组件用于过滤,还是应该使用第三方模块?

1 个答案:

答案 0 :(得分:1)

最后,我找到了解决方案。 看来Yii2通过DataFilter类提供了这种功能。 课程的官方documentation和使用guide的人

根据文档

  1. 定义模型进行验证。

    class SearchModel extends \yii\base\Model
    {
        public $id;
        public $name;
    
        public function rules()
        {
            return [
                [['id', 'name'], 'trim'],
                ['id', 'integer'],
                ['name', 'string'],
            ];
        }
    }
    
  2. 创建过滤器:

    $filter = new DataFilter(['searchModel' => $searchModel]);
    
  3. 用数据填充过滤器,验证

    if ($filter->load(\Yii::$app->request->get())) { 
       $filterCondition = $filter->build();
       if ($filterCondition === false) { // if error occure
           // the errors are stored in the filter instance
           return $filter;
       }
    }
    
  4. Query过滤器中使用构建条件

    $query->andWhere($filterCondition);