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