KillMeAgain 2015-07-15 15:53:12 13986次浏览 5条回复 20 12 0

由于Yii2 Controller Csrf验证是在beforeAction中完成的,所以在action中指定
$this->enableCsrfValidation = false;
不能实现局部关闭Csrf。

如何实现

新建一个Behavior

<?php
use Yii;
use yii\base\ActionEvent;
use yii\base\Behavior;
use yii\web\Controller;


class NoCsrf extends Behavior
{
    public $actions = [];
    public $controller;
    public function events()
    {
        return [Controller::EVENT_BEFORE_ACTION => 'beforeAction'];
    }
    public function beforeAction($event)
    {
        $action = $event->action->id;
        if(in_array($action, $this->actions)){
        	$this->controller->enableCsrfValidation = false;
        }
    }    
}

然后在Controller中添加Behavior

<?php

    public function behaviors()
    {
        return [
            'csrf' => [
                'class' => NoCsrf::className(),
                'controller' => $this,
                'actions' => [
                    'action-name'
                ]
            ]
        ];
    }

这样就实现了在action中关闭Csrf而不是在整个Controller中关闭。

Behavior Controller Yii2
觉得很赞
  • 回复于 2015-07-17 17:51 举报

    beforeAction里面这样应该也是可以的吧?

    
    public function beforeAction($action)
    {
        $this->enableCsrfValidation = false;
        return parent::beforeActin($action);
    }  
    
    
    5 条回复
    回复于 2015-07-20 14:00 回复

    这样写是关闭了controller 里面验证

    回复于 2015-07-20 14:04 回复

    这是关闭了controller里所有action的验证了csrf验证了吧.
    而且要全部关闭的话也不用那么麻烦,直接在controller里覆盖掉父类的enableCsrfValidation

    回复于 2015-07-28 13:10 回复

     if(in_array($action, $this->actions)){
            	$this->controller->enableCsrfValidation = false;
            }
    

    恩,我的意思是把parent::beforeAction放在设置enableCsrfValidation属性的后面,这里,你同样可以用in_array进行判断是否设置enableCsrfValidation不是么?

    回复于 2015-08-10 20:10 回复

    :请问一下,在yii 1中能用上面的方法?

    回复于 2015-10-19 14:29 回复

    好像不行

  • 回复于 2015-07-17 22:51 举报

    好使!赞一个。

  • 回复于 2015-07-21 09:11 举报

    原来可以这样~,我以前都是直接在beforeaction里关闭

  • 回复于 2015-07-21 14:54 举报

    good 点赞

  • 回复于 2015-08-06 10:23 举报

    其实 本质都是借助beforeAction事件 做处理, 当然了 结合behavior 更简洁, 更易于复用, 更符合开闭原则什么的...不过也带来一点点点点可以忽略不计的效率问题

您需要登录后才可以回复。登录 | 立即注册