调用“删除”操作:我收到_csrf_token [必需。]错误

时间:2011-07-12 07:49:04

标签: symfony1 symfony-1.4

我生成了模块“图片”,现在我正在尝试调用该动作 以这种方式“删除”:

  

frontend_dev.php /图片/删除/ ID / 1

但是我收到了这个错误:

  

500 |内部服务器错误| sfValidatorErrorSchema

     

_csrf_token [必需。]

     

在SF_ROOT_DIR / lib / vendor / symfony / lib / validator /中的堆栈跟踪()   sfValidatorSchema.class.php第110行......

$clean  = array();

$unused = array_keys($this->fields);

$errorSchema = new sfValidatorErrorSchema($this);

// check that post_max_size has not been reached

if (isset($_SERVER['CONTENT_LENGTH']) && (int) $_SERVER['CONTENT_LENGTH'] > $this-
     
    

的getBytes(ini_get( '的post_max_size')))

  
     

at sfValidatorSchema-> doClean(array('_ csrf_token'=> null))in   SF_ROOT_DIR / lib中/供应商/ symfony的/ lib目录/识别/   sfValidatorSchema.class.php第90行...... * /

     

public function clean($ values)

     

{

return $this->doClean($values);
     

}

     

/ ** at sfValidatorSchema-> clean(array('_ csrf_token'=> null))in   SF_ROOT_DIR / lib / vendor / symfony / lib / form / sfForm.class.php第247行......

有什么想法吗?

此致

哈维

sf 1.4

3 个答案:

答案 0 :(得分:1)

我强烈建议反对根据 dxb 建议注释掉CSRF保护。因为那时任何人都可以访问该删除URL并从数据库中删除内容。即使您将路由限制为post方法,任何熟悉Symfony的人都可以使用该URL删除数据库中的内容。

我愿意打赌问题在于您的删除网址链接。在您的模板中,如果您创建一个基本的HTML链接/锚点,如下所示:

<a href="www.mysite.com/frontend_dev.php/picture/delete/id/1>click me</a>

然后没有生成_csrf_token并且没有被传递。但是如果你使用Symfony的助手生成一个链接:

<?php echo link_to('click me', 'picture/delete?id=1') ?>

然后将生成链接以及一些插入名为_csrf_token的隐藏输入字段的javascript。此方法将正确地将CSRF令牌传递给删除操作,您将保护自己。

CSRF保护可以保护您。学习如何正确使用它总是比评论它并忽视它更好。

答案 1 :(得分:1)

您应该使用Symfony 1.4的内置功能来生成“删除”链接,该链接使用JavaScript对您的删除路由执行合法的POST请求并传递有效的CSRF令牌。

以下示例假设您有一个名为file_delete的路由,该路由接受一个数字参数id

// apps/frontend/config/routing.yml
file_delete:
  url:   /file/:id/delete
  param: { module: file, action: delete }
  requirements:
    id: \d+

生成一个“删除”链接,正确执行POST并添加CSRF令牌:

<?php
echo link_to('Delete', 'file_delete', array(
    'id' => $file->getId(),
), array(
    'method' => 'delete',
    'confirm' => 'Are you sure you want to delete this file?',
));
?>

虽然上面的代码有效,但我发现Symfony 1.4.18中仍然存在一个错误,导致您在单击“删除”链接后看到_csrf_token [Required.]。这是因为如果将撇号传递到confirm选项(例如Are you sure you're ready to proceed?),Symfony会生成带有语法错误的JavaScript。要确认JavaScript语法错误是罪魁祸首,请打开浏览器的控制台并单击该链接,然后查看错误,以便在重定向之前快速显示。就我而言,很容易从解决问题的confirm文本中删除撇号。

答案 2 :(得分:-1)

如果您通过表单或列表中的“删除”按钮调用删除操作,则可以尝试将UrlHelper.php中的错误功能_method_javascript_function()更新为此版本

function _method_javascript_function($method)
{
    $function = "var f = document.createElement('form'); f.style.display = 'none';     this.parentNode.appendChild(f); f.method = 'post'; f.action = this.href;";
    $varFlag = false;

    if ('post' != strtolower($method))
    {
        $varFlag = true;
        $function .= "var m = document.createElement('input'); m.setAttribute('type', 'hidden'); ";
        $function .= sprintf("m.setAttribute('name', 'sf_method'); m.setAttribute('value', '%s'); f.appendChild(m);", strtolower($method));
    }

    // CSRF protection
    $form = new BaseForm();
    if ($form->isCSRFProtected())
    {
        $function .= ($varFlag ? '' : 'var ')."m = document.createElement('input'); m.setAttribute('type', 'hidden'); ";
        $function .= sprintf("m.setAttribute('name', '%s'); m.setAttribute('value', '%s'); f.appendChild(m);", $form->getCSRFFieldName(), $form->getCSRFToken());
    }

    $function .= "f.submit();";

    return $function;
}