Yii2如何在gridview中正确创建批量操作的复选框列?

lal*_*alo 6 csrf yii csrf-protection yii2

我需要创建类似于wordpress帖子管理的"批量操作",因此您可以一次删除多个记录.

这是我的方法,并且工作正常,但我确信它不是最好的方法,因为这种方法容易受到CSRF攻击.

gridview中的复选框列:

GridView::widget([
'dataProvider' => $dataProvider,    
'columns' => [
['class' => 'yii\grid\CheckboxColumn'],
'id'=>'grid',
'country',
],
]); 
Run Code Online (Sandbox Code Playgroud)

触发函数的按钮

<a href="#" onclick="bulkAction('p');">
Run Code Online (Sandbox Code Playgroud)

功能:

<script>
    function bulkAction(a) {
        var keys = $('#grid').yiiGridView('getSelectedRows');
        window.location.href='<?php echo Url::to(['mycontroller/bulk']); ?>&action='+a+'&ids='+keys.join();
    }
</script>
Run Code Online (Sandbox Code Playgroud)

这个函数创建一个这样的URL:

index.php?r=mycontroller/bulk&action=1&ids=2,6,7,8
Run Code Online (Sandbox Code Playgroud)

问题是这种方法容易受到CSRF攻击(在此解释:http://blog.codinghorror.com/cross-site-request-forgeries-and-you/)

那么,什么是正确的方式呢?

lal*_*alo 10

我自己解决了这个问题:

这样,表单就会受到CSRF的保护,一切都在POST请求中.

这是观点:

<?=Html::beginForm(['controller/bulk'],'post');?>
<?=Html::dropDownList('action','',[''=>'Mark selected as: ','c'=>'Confirmed','nc'=>'No Confirmed'],['class'=>'dropdown',])?>
<?=Html::submitButton('Send', ['class' => 'btn btn-info',]);?>
<?=GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\CheckboxColumn'],
'id',
],
]); ?>
<?= Html::endForm();?> 
Run Code Online (Sandbox Code Playgroud)

这是控制器:

public function actionBulk(){
    $action=Yii::$app->request->post('action');
    $selection=(array)Yii::$app->request->post('selection');//typecasting
    foreach($selection as $id){
        $e=Evento::findOne((int)$id);//make a typecasting
        //do your stuff
        $e->save();
    }
    }
Run Code Online (Sandbox Code Playgroud)


Mih*_* P. 0

好吧,首先不要做你所做的事。就像你说的,这对 CRSF 是开放的。使用 POST 而不是 GET 将值传送到控制器。我相信,阿罗加乔夫的链接和答案可能会告诉您如何做到这一点。CRSF 的 1 个附加功能,您可以从 yii 获取页面的 CRSF,请查看这里Getting bad request (#400) on Ajax Calls using Yii 2 but not on the Accepted Answer (that is my :)) 但另一个。