Подтвердить что ты не робот

Laravel TokenMismatchException в ajax-запросе

Я использую группу ресурсов и использую этот фильтр для решения проблемы TokenMismatchException:

Route::filter('csrf', function($route, $request) {
    if (strtoupper($request -> getMethod()) === 'GET') {
        return;
        // get requests are not CSRF protected
    }

    $token = $request -> ajax() ? $request -> header('X-CSRF-Token') : Input::get('_token');

    if (Session::token() != $token) {
        throw new Illuminate\Session\TokenMismatchException;
    }
});

мой маршрут:

Route::group(array('prefix'=> 'admin', 'before' => 'csrf'), function(){
    Route::resource('profile' , 'ProfileController', array('as'=>'profile') );
});

в настоящее время. Я получаю ошибку для запросов Ajax, таких как этот код:

<script type="text/javascript">
    $(document).ready(function() {
       $('#frm').submit(function(e){
           e.preventDefault();
           name         = $('#name').val();
           family       = $('#family').val();
           email        = $('#email').val();
           currPassword = $('#currPassword').val();
           password     = $('#password').val();
           password_confirmation = $('#password_confirmation').val();     

           $.post("{{ route('admin.profile.update', $profile->id) }}",
                { 
                  _method : 'PUT',
                  name                  : name,
                  family                : family,
                  email                 : email,
                  currPassword          : currPassword,
                  password              : password,
                  password_confirmation : password_confirmation  
                },
                function(data)
                {
                    alert(data.errors.name);
                },'json');
                return false;
       });
});
</script>

ERROR:

{"error":{"type":"Illuminate\\Session\\TokenMismatchException","message":"","file":"\/var\/www\/alachiq\/app\/filters.php","line":83}}

Я думаю, что я должен быть отправлен _token в $.post. но я не могу получить тег input с атрибутом name. iget эту ошибку:

TypeError: 'stepUp' called on an object that does not implement interface HTMLInputElement.
4b9b3361

Ответ 1

В документах Laravel есть подсказка о том, как это сделать. Возможно, это не было доступно во время вопроса, но я подумал, что обновляю его с ответом.

http://laravel.com/docs/master/routing#csrf-x-csrf-token

Я проверил метод метатега из документации и получил его работу. Добавьте в свой глобальный шаблон следующий метатег

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

Добавьте этот JavaScript, который устанавливает значения по умолчанию для всех запросов ajax в jQuery. Предпочтительно в файле js, который включен в ваше приложение.

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
})

Этот токен может существовать в заголовке запроса или форме. Это заполняет его в заголовке запроса для каждого запроса ajax.

Ответ 2

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

<input type="hidden" name="_token" value="{{ csrf_token() }}" />

Другой метод

В вашем представлении вы можете установить объект с помощью _token

<script type="text/javascript">
    var _globalObj = {{ json_encode(array('_token'=> csrf_token())) }}
</script>

а затем при вызове ajax вы можете получить _token от объекта следующим образом:

var token = _globalObj._token;

и включить его в сообщение ajax.

Ответ 3

Просто выполните простую вещь, как я показал в следующем коде,

    $.ajax({
        type: 'POST',
        url: 'your-post-route-url',
        data: {
            "_token": "{{ csrf_token() }}",
            "form_data": $('#Form').serialize(),
        },
        success: function (data) {
            console.log(data);
        },
        error: function (reject) {
            console.log(reject);
        }
    });

Надеюсь, это самый простой способ решить эту проблему без какого-либо скрытого поля, и это работает для меня в версии laravel 5.4:)

Надеюсь, что это поможет.

Ответ 4

Вы также можете добавить URL-адрес, который дает вам ошибку внутри файла VerifyCsrfToken.php в

protected $except = [
    //
]

Скажем, ваш маршрут - сообщение. Вы можете просто добавить это

protected $except = ['post',
    //
];`... 

Надеюсь, что это поможет другим.

Ответ 5

  <html>
  <head>
  <title>Ajax Example</title>
      <meta name="csrf-token" content="<?php echo csrf_token() ?>" />    
  <script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js">
  </script>

  <script type="text/javascript">
        $.ajaxSetup({
          headers: {
              'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
          }
        });
  </script>

  <script>
     function getMessage(){
        $.ajax({
           type:'POST',
           url:'/getmsg',
           data:'_token = <?php echo csrf_token() ?>',
           data:'',
           success:function(data){
              $("#msg").html(data.msg);
           }
        });
     }
  </script>
  </head>

  <body>


  <div id = 'msg'>This message will be replaced using Ajax. 
     Click the button to replace the message.</div>
  <?php
     echo Form::button('Replace Message',['onClick'=>'getMessage()']);
  ?>
  </br>


  </body>

  </html>

и VerifyCsrfToken.php добавить эту функцию

protected function tokensMatch($request)
{
    // If request is an ajax request, then check to see if token matches token provider in
    // the header. This way, we can use CSRF protection in ajax requests also.
    $token = $request->ajax() ? $request->header('X-CSRF-Token') : $request->input('_token');

    return $request->session()->token() == $token;
}