Обновить CSRF после отправки формы - PullRequest
1 голос
/ 11 апреля 2020

Я хочу достичь функциональности, которую я показываю на этом изображении. Пользователи будут нажимать на кнопки редактирования и активировать формы для отдельных полей на странице.

enter image description here

Используя Ajax, я обновлю модель и восстановите дисплей снова после успеха. Проблема здесь в CSRF_TOKEN. После того, как пользователь обновит первое поле, независимо от того, какое оно будет, второе редактирование вернет сообщение о несоответствии токенов ошибки 500.

Я испробовал много разных подходов, включая последний, который я видел здесь:

$.ajaxSetup( {
  beforeSend: function( xhr, settings ){
    function getCookie( name ){
      var cookieValue = null;

      if( document.cookie && document.cookie != '' ){
        var cookies = document.cookie.split( ';' );
        for( var i = 0; i < cookies.length; i++ ){
          var cookie = jQuery.trim( cookies[ i ] );
          // Does this cookie string begin with the name we want?
          if( cookie.substring( 0, name.length + 1 ) == ( name + '=' ) ){
            cookieValue = decodeURIComponent( cookie.substring( name.length + 1 ) );
            break;
          }
        }
      }
      return cookieValue;
    }
    if( !( /^http:.*/.test( settings.url ) || /^https:.*/.test( settings.url ) ) ){
      // Only send the token to relative URLs i.e. locally.
      xhr.setRequestHeader( "X-CSRFToken", getCookie( 'csrftoken' ) );
    }
  }
} );

но все равно я получаю сообщение об ошибке при второй отправке. Я знаю, что все, что мне нужно сделать, это обновить значение токена в моем мета <meta name="csrf-token" content="{{ csrf_token() }}">, но у меня закончились идеи о том, как это сделать, и я действительно хочу сохранить эту функциональность без ссылки на страницу sh.

Может быть, отправить новый CSRF с контроллера, который возвращает результат, и использовать что-то вроде $( 'meta[name="csrf-token"]' ).val( response.csrf ); в моем успешном этапе в запросе ajax?

Ответы [ 2 ]

0 голосов
/ 11 апреля 2020

Мой ответ состоит в изменении как минимум двух файлов: шаблона, в котором выполняется ajax, и контроллера, который получает запрос формы. Все методы, которые получают действия от форм на странице, должны возвращать обновленный токен csrf, и все поля (если таковые имеются), которые содержат значение csrf, также должны обновляться после выполнения ajax.

Сначала, шаблон blade-сервера будет использовать общий токен csrf для всех форм в документе, для этого я добавил мета-токен csrf в свой раздел заголовка, как обычно:

<meta name="csrf-token" content="{{ csrf_token() }}">

Теперь ajax скрипт должен вставить в форму токен и обновить мета после выполнения любой из форм в шаблоне:

$( 'body' ).on( 'submit', '.form', function( event ){
  event.preventDefault();
  let fd = new FormData( $( this )[ 0 ] );
  fd.append( '_token', $( 'meta[name="csrf-token"]' ).attr( 'content' ) )

  $.ajax( {
    url : '{{ route( 'service.update', [ 'service' => $service ] ) }}',
    method : 'post',
    data : fd,
    contentType: false,
    processData: false,
    success: function( response ){
      $( 'meta[name="csrf-token"]' ).attr( 'content', response.token );
      //Do all the other things that need to be done...
    },
    error: function( xhr, status, error ){
      console.log( error );
    }
  } );
} );

Теперь первое, что я делаю, это создаю объект FormData с содержимым сформируйте и добавьте значение csrf из мета в набор полей (fd.append( '_token', $( 'meta[name="csrf-token"]' ).attr( 'content' ) )).

После завершения выполнения my javascript получит ответную переменную со значением .token, которая содержит новый csrf -token value, поэтому я обновляю старое мета-значение fre sh one: $( 'meta[name="csrf-token"]' ).attr( 'content', response.token );.

Теперь для стороны контроллера все, что мне нужно сделать, это добавить к jSon, токену v alue, в моем случае это массив, поэтому мне нужно только добавить его следующим образом:

$response[ 'token' ] = $request->session()->token();
return $response;

Теперь формы будут работать нормально, спасибо

0 голосов
/ 11 апреля 2020
       $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
            }
        });
...