Fetch API validateCsrf failed

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Аватара пользователя
leonidps
Сообщения: 268
Зарегистрирован: 2011.01.18, 19:40
Откуда: Псков

Fetch API validateCsrf failed

Сообщение leonidps »

есть надобность вместо AJAX использовать Fetch API
Если AJAX validateCsrf успешна то fetch validateCsrf провалена
Для примера простая задача загрузка данных для select

Код: Выделить всё

let hAddress = document.querySelector(".house-address");
let hService = document.querySelector(".house-service");
let pUrl = '/index.php?r=options%2Fservice-house';
let param = document.querySelector('meta[name="csrf-param"]').content;
let token = document.querySelector('meta[name="csrf-token"]').content;
let pData = {};
pData[param] = token;

hAddress.addEventListener('change', function () {
    let pVal = this.options[this.selectedIndex].value;
    pData['house_id'] = pVal;
    getOptionsByFetchPost(pUrl);
});
function getOptionsByFetchPost(pUrl) {
    fetch(pUrl, {
        method: 'POST', 
        body: JSON.stringify(pData), 
        headers: {
            'Content-Type': 'text/html'
        }
    })
            .then((response) => {
                return response.text()
            })
            .then((html) => {
//                console.log(html);
                hService.innerHTML = html;
            })
            .catch(err => console.error(err))
            ;
}
Ответ соответственно Bad Request (#400)Не удалось проверить переданные данные.
Выбрасывает в /web/Controller /web/Request->validateCsrfToken()...
Правила существуют не только для того, чтобы их нарушать.
Аватара пользователя
leonidps
Сообщения: 268
Зарегистрирован: 2011.01.18, 19:40
Откуда: Псков

Re: Fetch API validateCsrf failed

Сообщение leonidps »

некоторые результаты могут быть интересны
для успешной csrf валидации AJAX POST достаточно значение токена включить в POST-параметр
для успешной csrf валидации fetch POST значение токена включить в заголовок X-СSRF-TOKEN
например

Код: Выделить всё

    let myHeaders = new Headers();
    myHeaders.append('X-CSRF-Token', token);
Насколько это корректно, не беру ответственность
Одного взгляда на ~2000 строк /web/Request мне хватило чтобы отказаться от каких-либо изысканий.
Тем более что уже идет разработка 3 версии
Правила существуют не только для того, чтобы их нарушать.
Sasha_ch
Сообщения: 80
Зарегистрирован: 2011.04.10, 15:59
Откуда: Киев

Re: Fetch API validateCsrf failed

Сообщение Sasha_ch »

Итого получается как-то так:

Код: Выделить всё

function getOptionsByFetchPost(pUrl) {
  fetch(pUrl, {
    method: 'POST',
    body: JSON.stringify(pData),
    headers: {
      'Content-Type': 'application/json',
      'X-CSRF-Token': yii.getCsrfToken(),
    }
  })
    .then((response) => {
      return response.text()
    })
    .then((html) => {
      hService.innerHTML = html;
    })
    .catch(err => console.error(err));
}
Arroyo
Сообщения: 105
Зарегистрирован: 2014.11.29, 11:24

Re: Fetch API validateCsrf failed

Сообщение Arroyo »

Спасибо, помогло. Никак ответ не мог найти, что токен в заголовки нужно записывать
Ответить