处理 CSRF 和 XSRF 令牌错误消息

dealing with CSRF and XSRF-token error messages

这个问题与一个仍然无法解决的问题相关联,但我现在已经非常准确地确定了它,并且我专注于我所知道的错误原因,但我已经尝试了我所知道的所有方法。

问题是从 jquery 到控制器的 $.post 会抛出 500 内部服务器错误,这实际上是在第 67 行捕获的 "mismatch token exception" VerifyCSRFToken.php 文件。

所以controller取不到值,因为Middleware一直在中间

为了尝试解决这个问题,我做了:

1) 转到 App\Middleware\VerifyCSRFToken.php 并包含 jquery 代码段中的路由以被忽略。这应该足够了,但还不够。

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = ['findcountries', 'findpaises','prueba'];
}

2) 另外,我在查看页面中添加了这个元标记。 (实际上,如果我想允许使用 csrf 发送的话)

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

3) 我包含了我从视图中调用的代码片段

// public/js/config.js
$(function () {
    $.ajaxSetup({
        headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') }
    });
});

令我困惑的是,它是在我的生产服务器上工作了几个月的复制粘贴代码,实际上 CSRFVerifyToken php 文件中的忽略路由起到了作用,我什至不需要元标记和另一个片段。

现在我在cloud9中开发一个改进版的web也无法摆脱这个问题

有人知道可以做些什么吗?

谢谢 更新

这是给出问题的代码:

    function cargarProvincias() {        

            var country = $('#country').val();       
              $url = "{{URL::route('findcountries')}}";   

 this one ==>       $.post($url, {pais:country},function(data){
                    $('#regions').empty();                 
                    $.each(data, function(key, value){                 
                    $('#regions').append('<option value="' + key + '">' + value + '</option>')});
                        cargarCiudades();         
                  });
              }

您使用的令牌来自元标记,这是错误的。假设您在同一个页面上有 2 个不同的表单,这是行不通的!

您应该在 Laravel 生成的表单中使用令牌。我从另一个可能对您有帮助的问题中获取此代码。

How to call route of controller with ajax serialize

var formId = '#radicado';

var token = document.getElementById('token').value;
$.ajax({
    async: true,
    headers: {'X-CSRF-TOKEN': token},
    url: ip+'/storeVersion',
    type:  'POST',
    data: $(formId).serialize(),
    dataType: 'html',
    success: function(result){
        $(formId)[0].reset();
        alert(result);
        document.getElementById("version").style.display = "none";
        document.getElementById("preview").style.display = "none";
        parent.formulario.location.reload() 
    },
    error: function(){
        alert('No se ha actualizado el documento.');
    }
});

请记住,CSRF 令牌位于您尝试发送的表单中。

问题出在开发c9.io的httpS SSL加密环境

我在页面中的内容,要么从google调用js,不在https下,而是在http下,因为混合内容冲突而被阻止。

我禁用了浏览器保护以使其全部为 http,但是 https 下的站点随后会告诉我我正在进行某种跨站点请求伪造,因为表单 (http) 的来源不是与环境相同 (https)

因此,只有当表单所在页面的 URL 不在 https 下时,代码才会起作用。我可以即时编辑 headers,在 http 中删除或添加 s,然后查看成功或失败的结果。

我首先摆脱了表格,只留下一个 select 列表和一个简单的 select 列表以及这个非常简单的 jquery 代码:

<script>

    jQuery(document).ready(function () {
    cargarProvincias();
 //   cargarCiudades();
    $('#country').change(cargarProvincias);

     });

        function cargarProvincias() {     

        var country = $('#country').val();   
      //  alert(country);
          $url = "{{ URL::route('findcountries')}}";   
         // alert($url);
          $.post($url, {input:country},function(data){
               $('#feedback').text(data);
          });

        }

   </script> 

然后我将这个 select 列表放在一个表单中,没问题。像这样:

{!! Form::open(array('route' => 'property.store', 'files'=>true)) !!}

第一张图片,如果我从这里删除路由,你会看到500错误:

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [ 'findpaises','prueba','/', 'propertyfound'];
}

因此,正如我所说,如果且仅当您将其包含在上面的忽略列表数组中时,您可以不在 Ajax 或表单中发送任何 CSRF。

另外我必须说,Firefox 不是检查开发问题的好浏览器。您可能已经解决了这个问题,firefox 将保留其存储的错误。

今天我发现了 slimjet 作为浏览器,如果你使用它你就会明白我的意思。 Firefox 由于其该死的插件而使我的计算机崩溃,而在 Slimjet

中一切都是 built-in