Yii dropzone扩展(无法验证CSRF令牌)

时间:2014-03-17 11:08:27

标签: php ajax file-upload yii

我想发布带有dropzone请求的Yii csrftoken,这是我的代码

   $this->widget('ext.dropzone.EDropzone', array(
            'model' => $model,
            'attribute' => 'file',
            'url' => $this->createUrl('//media/file'),
            'mimeTypes' => array('image/jpeg', 'image/png'),
            'options' => array('sending' => 'function(file, xhr, formData) {
     formData.append("YII_CSRF_TOKEN", "' . Yii::app()->request->csrfToken . '");
                  }',),
        ));

// controller>媒体(它无法访问控制器)

    public function actionFile() {
    $save_path = Yii::app()->basePath . '/../media/portfolio/';
    $save_url = Yii::app()->createAbsoluteUrl('//media/portfolio/');

    if (empty($_FILES) === false) {
        $file_name = $_FILES['Company'] ['name']['file'];
        $fileType = $_FILES['Company']['type']['file'];
        $tmp_name = $_FILES['Company']['tmp_name']['file'];
        $file_size = $_FILES['Company']['size']['file'];
        $temp_arr = explode(".", $file_name);
        $file_ext = array_pop($temp_arr);
        $file_ext = trim($file_ext);
        $file_ext = strtolower($file_ext);
        if (!file_exists($save_path))
            mkdir($save_path);
        $new_file_name = rand(0,1000) . '.' . $file_ext;
        $file_path = $save_path . $new_file_name;
        move_uploaded_file($tmp_name, $file_path);
    }
}

2 个答案:

答案 0 :(得分:0)

这是我发现在我的搜索中使用CSRF令牌与xupload / blueimp jquery文件上传器一起工作。把它放在文件" EHttpRequest.php" (或创建它)在组件目录中。

来源:http://www.yiiframework.com/forum/index.php/topic/14500-re-writing-a-class-method-without-editing-framework-files/

<?php 
class EHttpRequest extends CHttpRequest
{
    public function validateCsrfToken($event)
    {
        if($this->getIsPostRequest())
        {
            $cookies=$this->getCookies();
            if($cookies->contains($this->csrfTokenName) && isset($_POST[$this->csrfTokenName]) || isset($_GET[$this->csrfTokenName] ))
            {
                $tokenFromCookie=$cookies->itemAt($this->csrfTokenName)->value;
                $tokenFrom=!empty($_POST[$this->csrfTokenName]) ? $_POST[$this->csrfTokenName] : $_GET[$this->csrfTokenName];           
                $valid=$tokenFromCookie===$tokenFrom;
            }
            else
                $valid=false;
            if(!$valid)
                throw new CHttpException(400,Yii::t('yii','Lite: The CSRF token could not be verified.'));
        }
    }
}
?>

警告:这样做可能存在一些安全风险,如果有人发现此安全问题有任何问题,请与我联系。

答案 1 :(得分:0)

这是如何阻止某些操作的CsrfValidation

//main/config 

在组件

下添加以下行
       'request' => array(
        'class' => 'HttpRequest',
        'noCsrfValidationRoutes' => array(
            '^site/upload.*$',
        ),
        'enableCookieValidation' => true,
        'enableCsrfValidation' => true,
    ),

然后在组件文件夹

class HttpRequest extends CHttpRequest
{
public $prev_url;

public $noCsrfValidationRoutes = array();


protected function normalizeRequest()
{
    parent::normalizeRequest();

    if(!isset($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] != 'POST')
    {
        return;
    }

    $route = Yii::app()->getUrlManager()->parseUrl($this);
    if($this->enableCsrfValidation)
    {
        foreach($this->noCsrfValidationRoutes as $cr)
        {
            if(preg_match('#'.$cr.'#', $route))
            {
                Yii::app()->detachEventHandler('onBeginRequest', array($this,'validateCsrfToken'));
                Yii::trace('Route "'.$route.' passed without CSRF validation');
                break; // found first route and break
            }
        }
    }
}

public function getCurrentUri()
{
    // Get HTTP/HTTPS (the possible values for this vary from server to server)
    $myUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] && !in_array(strtolower($_SERVER['HTTPS']),array('off','no'))) ? 'https' : 'http';
    // Get domain portion
    $myUrl .= '://'.$_SERVER['HTTP_HOST'];
    // Get path to script
    $myUrl .= $_SERVER['REQUEST_URI'];
    // Add path info, if any

    $get = $_GET; // Create a copy of $_GET
    if (count($get)) { // Only add a query string if there's anything left
      $myUrl .= '?'.http_build_query($get);
    }

    return $myUrl;
}
}