Symfony1 呼唤;删除“;操作:我获取_csrf_令牌[必需]]错误

Symfony1 呼唤;删除“;操作:我获取_csrf_令牌[必需]]错误,symfony1,symfony-1.4,Symfony1,Symfony 1.4,我生成了模块“picture”,现在我正在尝试调用该操作 以这种方式“删除”: frontend_dev.php/picture/delete/id/1 但我得到了这个错误: 500 |内部服务器错误| sfValidatorErrorSchema _csrf_令牌[必需。] SF_ROOT_DIR/lib/vendor/symfony/lib/validator中()处的堆栈跟踪/ sfValidatorSchema.class.php第110行 $clean = array(); $un

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

frontend_dev.php/picture/delete/id/1

但我得到了这个错误:

500 |内部服务器错误| sfValidatorErrorSchema

_csrf_令牌[必需。]

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\u get('post\u max\u size'))

在中的sfValidatorSchema->doClean(数组(''u-csrf\u-token'=>null')处 SF_ROOT_DIR/lib/vendor/symfony/lib/validator/ sfValidatorSchema.class.php第90行*/

公共功能清洁($价值)

{

return $this->doClean($values);
}

/**在中的sfValidatorSchema->clean(数组(''u-csrf\u-token'=>null')处 SF_ROOT_DIR/lib/vendor/symfony/lib/form/sfForm.class.php第247行

有什么想法吗

问候

哈维


sf 1.4

我强烈建议不要评论dxb建议的CSRF保护。因为这样任何人都可以访问删除url并从数据库中删除内容。即使您将路由限制为
post
方法,熟悉Symfony的任何人都可以使用url从数据库中删除内容

我敢打赌问题在于你的链接指向删除url。在模板中,如果您创建如下基本HTML链接/锚定:

<a href="www.mysite.com/frontend_dev.php/picture/delete/id/1>click me</a>
<?php echo link_to('click me', 'picture/delete?id=1') ?>
然后该链接将与一些javascript一起生成,这些javascript插入一个名为
\u csrf\u token
的隐藏输入字段。此方法将正确地将CSRF令牌传递给删除操作,您将保护自己


CSRF保护是为了保护您。学习如何正确使用它总比评论它和忽略它要好。

我强烈建议不要像dxb建议的那样评论CSRF保护。因为这样任何人都可以访问删除url并从数据库中删除内容。即使您将路由限制为
post
方法,熟悉Symfony的任何人都可以使用url从数据库中删除内容

我敢打赌问题在于你的链接指向删除url。在模板中,如果您创建如下基本HTML链接/锚定:

<a href="www.mysite.com/frontend_dev.php/picture/delete/id/1>click me</a>
<?php echo link_to('click me', 'picture/delete?id=1') ?>
然后该链接将与一些javascript一起生成,这些javascript插入一个名为
\u csrf\u token
的隐藏输入字段。此方法将正确地将CSRF令牌传递给删除操作,您将保护自己


CSRF保护是为了保护您。学习如何正确地使用它总比注释它并忽略它要好。

如果您通过表单或列表中的“删除”按钮调用删除操作,那么您可以尝试将UrlHelper.php中的buggy function\u method\u javascript\u 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;
}

如果您通过表单或列表中的“delete”按钮调用delete操作,那么您可以尝试将UrlHelper.php中的buggy function\u method\u javascript\u 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;
}

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

以下示例假设您有一个名为
file\u 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?',
));
?>


虽然上面的代码有效,但我发现一个bug在Symfony 1.4.18中仍然存在,它可能导致您在单击删除链接后看到
\u csrf\u令牌[必需]
。这是由于Symfony在将撇号传递到
确认
选项(例如
您确定准备好继续了吗?
)时生成了带有语法错误的JavaScript。要确认JavaScript语法错误是罪魁祸首,请打开浏览器的控制台并单击链接,然后观察错误是否会在重定向之前快速显示。在我的例子中,很容易从解决问题的
确认
文本中删除撇号。

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

以下示例假设您有一个名为
file\u 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?',
));
?>

虽然上面的代码有效,但我发现一个bug在Symfony 1.4.18中仍然存在,它可能导致您在单击删除链接后看到
\u csrf\u令牌[必需]
。这是由于Symfony在将撇号传递到
确认
选项(例如
您确定准备好继续了吗?
)时生成了带有语法错误的JavaScript。要确认JavaScript语法错误是罪魁祸首,请打开浏览器的控制台并单击链接,然后观察错误是否会在重定向之前快速显示。在我的例子中,很容易从解决问题的
confirm
文本中删除撇号