Вызов действия «удалить»: я получаю ошибку _csrf_token [обязательно.] - PullRequest
1 голос
/ 12 июля 2011

Я сгенерировал модуль «picture» и теперь пытаюсь вызвать действие «delete» следующим образом:

frontend_dev.php / picture / delete / 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')))

в sfValidatorSchema-> doClean (массив ('_ csrf_token' => null)) в SF_ROOT_DIR / lib / vendor /symfony / lib / validator / sfValidatorSchema.class.php строка 90 ... * /

чистая открытая функция ($ values)

{

return $this->doClean($values);

}

/ ** в sfValidatorSchema-> clean (массив ('_ssrf_token' => null)) в SF_ROOT_DIR / lib / vendor / symfony / lib / form / sfForm.class.php, строка 247 ...

Есть идеи?

С уважением

Хави

sf 1.4

Ответы [ 3 ]

1 голос
/ 18 ноября 2012

Вы должны использовать встроенную возможность 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.] после нажатия на ссылку Удалить.Это связано с тем, что Symfony генерирует JavaScript с синтаксической ошибкой при передаче апострофа в опцию confirm (например, Are you sure you're ready to proceed?).Чтобы убедиться, что синтаксическая ошибка JavaScript является виновной, откройте консоль браузера и нажмите на ссылку, а затем просмотрите сообщение об ошибке, которое будет отображаться быстро, прежде чем оно будет перенаправлено.В моем случае было легко удалить апостроф из текста confirm, который исправил проблему.

1 голос
/ 09 августа 2011

Я бы настоятельно рекомендовал ПРОТИВ закомментировать защиту CSRF в соответствии с dxb . Потому что тогда любой сможет получить доступ к этому 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') ?>

Затем будет сгенерирована ссылка вместе с некоторым javascript, который вставляет скрытое поле ввода с именем _csrf_token. Этот метод правильно передаст токен CSRF в действие удаления, и вы защитите себя.

Защита CSRF защищает вас. Изучить, как правильно его использовать, всегда лучше, чем комментировать его и пренебрегать им.

0 голосов
/ 17 мая 2012

Если вы вызываете действие удаления с помощью кнопки «Удалить» в форме или списке, вы можете попытаться обновить ошибочную функцию _method_javascript_function () в UrlHelper.php до этой версии

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;
}
...