处理CSRF和XSRF令牌错误消息

时间:2016-04-15 12:53:06

标签: laravel csrf

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

问题是从jquery到控制器的$ .post会抛出500内部服务器错误,这实际上是在VerifyCSRFToken.php文件的第67行中捕获的“不匹配令牌异常”。

因此,控制器没有获得该值,因为中间件停留在中间

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

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文件中的忽略路由完成了这个技巧,我甚至不需要metatag和其他代码段。

现在我在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 个答案:

答案 0 :(得分:2)

The token you're using is from metatags, that's wrong. Let's say you have 2 different forms on the same page, it won't work!

You should use the token inside the form generated by Laravel. I grab this code from another question that may help you.

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.');
    }
});

Remember, the CSRF token is inside the form you're trying to send.

答案 1 :(得分:-1)

问题在于开发了c9.io的httpS SSL加密环境。

我在页面中显示的内容,是从谷歌调用不属于https的js,但http会因为混合内容的冲突而被阻止。

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

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

我首先删除了Form,只留下了一个选择列表和一个简单的简单选择列表和这个非常简单的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> 

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

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

This is what happens if you remove the route from Exclusion CSRFVerifyFile

302

changing headers

200 ok

第一张图片,如果我从这里删除路线,你会看到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或你的表单IF中发送任何CSRF,只要你将它包含在上面的忽略列表数组中。

另外我必须说,Firefox不是检查开发问题的好浏览器。你可能已经解决了这个问题,firefox会在存储错误的情况下休息。

今天我发现slimjet作为浏览器,如果你使用它,你会看到我的意思。 Firefox因为它的血腥插件而崩溃了我的电脑,而Slimjet内置了所有内容