Недопустимый токен CSRF. Пожалуйста, попробуйте отправить форму

Я получаю это сообщение об ошибке каждый раз, когда я пытаюсь представить форме:

недопустимый маркер CSRF. Пожалуйста, попробуйте повторно отправить форму

мой код такой:

<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal">
    <div class="form-group">
        {{ form_label(form.email, 'Email', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
        {{ form_widget(form.email, {'attr': {'class': 'col-md-2'}}) }}
        {{ form_errors(form.email) }}
    </div>

    <div class="form-group">
        {{ form_label(form.nickname, 'Nickname', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
        {{ form_widget(form.nickname, {'attr':{'class': 'col-md-2'}}) }}
        {{ form_errors(form.nickname, {'attr': {'class': 'col-md-3'}}) }}
    </div>
    <div class="form-group">
        {{ form_label(form.password, 'password', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
        {{ form_widget(form.password, {'attr': {'class': 'col-md-2'}}) }}
        {{ form_errors(form.password, {'attr': {'class': 'col-md-3'}}) }}
    </div>

    <div class="form-group">
        {{ form_label(form.password_repeat, 'Repeat password', {'label_attr': {'class': 'col-md-1 control-label'}}) }}
        {{ form_widget(form.password_repeat, {'attr':{'class': 'col-md-2'}}) }}
        {{ form_errors(form.password_repeat, {'attr': {'class': 'col-md-3'}}) }}
    </div>
    <div class="form-group">
        <div class="col-md-1 control-label">
        <input type="submit" value="submit">
    </div>

    </div>
</form>

какие идеи?

13 ответов


вам нужно добавить _token в форме я.е

{{ form_row(form._token) }}

на данный момент в вашей форме отсутствует поле токена CSRF. Если вы используете функции формы веточки для отображения вашей формы, как form(form) это автоматически отобразит поле токена CSRF для вас, но ваш код показывает, что вы визуализируете свою форму с raw HTML, как <form></form>, поэтому вам нужно вручную отобразить поле.

или просто добавьте {{ form_rest(form) }} перед закрывающим тегом формы.

согласно docs

это отображает все поля, которые еще не были отображены для данного форма. Это хорошая идея, чтобы всегда иметь это где-то внутри формы. как он будет отображать скрытые поля для вас и сделать любые поля, которые вы забыли чтобы сделать более очевидным (так как он будет отображать поле для вас).

form_rest (просмотр, переменные)


Также вы можете увидеть это сообщение об ошибке, если ваша форма имеет много элементов.

эта опция в php.ini причина проблемы

; How many GET/POST/COOKIE input variables may be accepted
 max_input_vars = 1000

проблема в том, что _token пропускает запрос PUT (GET) Таким образом, вы можете увеличить стоимость.

кроме того, это касается больших файлов. Увеличение

upload_max_filesize

опция решит проблему


это происходит потому, что формы по умолчанию содержат защиту CSRF, которая в некоторых случаях не требуется.

вы можете отключить эту защиту CSRF в своем классе формы в getDefaultOptions способ такой:

// Other methods omitted

public function getDefaultOptions(array $options)
{
    return array(
        'csrf_protection' => false,
        // Rest of options omitted
    );
}

если вы не хотите отключать защиту CSRF, вам нужно отобразить поле защиты CSRF в вашей форме. Это можно сделать с помощью {{ form_rest(form) }} в вашем файле представления, например:

<form novalidate action="{{path('signup_index')}}" method="post" {{form_enctype(form)}} role="form" class="form-horizontal">
    <!-- Code omitted -->

    <div class="form-group">
        <div class="col-md-1 control-label">
            <input type="submit" value="submit">
        </div>

    </div>
    {{ form_rest(form) }}
</form>

{{ form_rest(form) }} отображает все поля, которые вы не ввели вручную.


перед </form> tag put:

{{ form_rest(form) }}

он автоматически вставит другие важные (скрытые) входы.


в дополнение к другим предложениям вы можете получить ошибки токена CSRF, если ваше хранилище сеансов не работает.

в недавнем случае мой коллега изменил "session_prefix" на значение, в котором было пробел.

session_prefix: 'My Website'

это сломанное хранилище сеансов, что, в свою очередь, означало, что моя форма не смогла получить токен CSRF из сеанса.


У меня была эта проблема со странным поведением: очистка кэша браузера не исправила ее, но Очистка файлов cookie (то есть файла cookie идентификатора сеанса PHP) решила проблему.

Это должно быть сделано после вы проверили все другие ответы, включая проверку вас do имейте токен в скрытом поле ввода формы.


недавно у меня была эта ошибка. Оказывается, Мои настройки cookie были неправильными в config.в формате YML. Добавление cookie_path и cookie_domain параметры framework.session исправил.


Если вы не хотите использовать form_row или form_rest и просто хотите получить доступ к значению _token в шаблоне twig. Используйте следующее:

<input type="hidden" name="form[_token]" value="{{ form._token.vars.value }}" />

в моем случае у меня возникли проблемы с аннотацией maxSize в сущности, поэтому я увеличил ее с 2048 до 20048.

 /**
 * @Assert\File(
 *     maxSize = "20048k",
 *     mimeTypes = {"application/pdf", "application/x-pdf"},
 *     mimeTypesMessage = "Please upload a valid PDF"
 * )
 */
private $file;

надеюсь, что этот ответ поможет!


если вы преобразовали свою форму из простого HTML в twig, убедитесь, что вы не пропустили удаление закрытия </form> - тег. Глупая ошибка, но как я обнаружил, это возможная причина этой проблемы.

когда я получил эту ошибку, я не мог понять сначала. Я использую form_start() и form_end() для генерации формы, поэтому я не нужно явно добавлять маркер С form_row(form._token), или использовать form_rest() чтобы получить его. он уже должен был быть добавлен автоматически form_end().

проблема заключалась в том, что представление, с которым я работал, было преобразовано из простого HTML в twig, и я пропустил удаление закрытия </form> - тег, поэтому вместо :

{{ form_end(form) }}

я:

</form>
{{ form_end(form) }}

это на самом деле похоже на то, что может вызвать ошибку, но, по-видимому, это не так, поэтому когда form_end() выходы form_rest(), форма уже закрыта. Фактический сгенерированный источник страницы формы был похож это:

<form>
    <!-- all my form fields... -->
</form>
<input type="hidden" id="item__token" name="item[_token]" value="SQAOs1xIAL8REI0evGMjOsatLbo6uDzqBjVFfyD0PE4" />
</form>

очевидно, решение удалить лишний закрывающий тег и может выпить еще кофе.


Я столкнулся с аналогичной проблемой. После того, как поле токена было фактически отображено (см. принятый ответ), я проверил свои куки. Было 2(!) cookies для домена в моем браузере Chrome, по-видимому, потому, что я запускал приложение в том же домене, что и другое приложение, но с другим портом (т. е. mydomain.com установите исходный файл cookie, пока приложение buggy работает на mydomain.com: 123) Теперь, по-видимому, Chrome отправил неправильный cookie, поэтому защита CSRF не смогла связать токен с правильный сеанс.

Fix: очистите все куки для рассматриваемого домена, убедитесь, что вы не запускаете несколько приложений в одном домене с разными портами.


у меня была та же ошибка, но в моем случае проблема заключалась в том, что мое приложение использовало несколько доменов первого уровня, в то время как cookie использовал один. Удаление cookie_domain: ".%domain%" с framework.session на config.yml вызвал cookies по умолчанию для любого домена, в котором была форма, и это исправило проблему.


это кажется проблемой при использовании bootstrap, если вы не визуализируете форму с помощью {{ form (form)}}. Кроме того, проблемы, похоже, возникают только при вводе type="hidden". Если вы проверите страницу с формой, вы обнаружите, что скрытый ввод не является частью разметки вообще или он визуализируется, но не передается по какой-либо причине. Как было предложено выше, добавление {{form_rest (form)}} или упаковка ввода, как показано ниже, должны сделать трюк.

<div class="form-group">
    <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
</div>