从iframe内部发布时出现Laravel TokenMismatchExpected


Laravel TokenMismatchExpection when posting from inside an iframe

我有一个在http://some.example.com/myiframes/default.aspx上运行的页面。这个页面有一个iframe。iframe源代码/包含一个Laravel 5.2基础应用程序。

我的Laravel页面URL"这是iframe的来源"是https://laravel.example.com.

https://laravel.example.com有一个带有提交按钮的表单。当用户点击它时,他/她会点击同一域上的另一条路由,即。https://laravel.example.com/disply/survey

但每次提交表格时,我都会收到以下异常

TokenMismatchException in VerifyCsrfToken.php line 67:

为了确保我清楚,在http://some.example.com/myiframes/default.aspx页面上,我的代码看起来像这个

在我位于https://laravel.example.com的laravel应用程序上,这是我的表单

    <form method="POST" action="https://laravel.example.com/disply/survey" accept-charset="UTF-8" class="form">
<input name="_token" type="hidden" value="Dk6SN4WzO4brbvdnBO6JZ7e1lBGjmYz8GQJ1lYFo">
<input name="survey_id" type="hidden" value="10">
<input name="call_id" type="hidden" value="667">
<input name="pools" type="hidden">
<input name="alt_id_1" type="hidden" value="250">
<input name="alt_id_2" type="hidden" value="5">
<input name="alt_id_3" type="hidden">
<input name="alt_id_4" type="hidden">
<input name="alt_id_5" type="hidden">
<input name="alt_id_6" type="hidden">
<input name="alt_id_7" type="hidden">
<input name="alt_id_8" type="hidden">
<input name="alt_id_9" type="hidden">
<input name="alt_id_10" type="hidden">

<input name="alt_string_1" type="hidden">
<input name="alt_string_2" type="hidden">
<input name="alt_string_3" type="hidden">
<input name="alt_string_4" type="hidden">
<input name="alt_string_5" type="hidden">
<input name="alt_string_6" type="hidden">
<input name="alt_string_7" type="hidden">
<input name="alt_string_8" type="hidden">
<input name="alt_string_9" type="hidden">
<input name="alt_string_10" type="hidden">
<div class="text-center"> 
    <input class="btn btn-primary" type="submit" value="Start Survey">
</div>
</form>

该表单在iframe之外非常有效。只有当我在iframe内部时,问题才会出现。

我打开了位于App'Http'Middleware中的VerifyCsrfToken类,并添加了http://some.example.com插入$except数组中,但该数组没有解决问题。

protected $except = [
    'http://some.example.com'
];

是什么原因导致了这个问题?我该如何纠正这个问题?

编辑,这是我的模板

{!! Form::open([
                'url' => route('my.surveys.display'),
                'class' => 'form',
                'method' => 'post'
                ]) !!}
{!! Form::hidden('survey_id', $survey_id) !!}
{!! Form::hidden('call_id', $call_id) !!}
{!! Form::hidden('pools', $pools) !!}
{!! Form::hidden('call_type', $type) !!}

{!! Form::hidden('alt_id_1', $alt_id_1) !!}
{!! Form::hidden('alt_id_2', $alt_id_2) !!}
{!! Form::hidden('alt_id_3', $alt_id_3) !!}
{!! Form::hidden('alt_id_4', $alt_id_4) !!}
{!! Form::hidden('alt_id_5', $alt_id_5) !!}
{!! Form::hidden('alt_id_6', $alt_id_6) !!}
{!! Form::hidden('alt_id_7', $alt_id_7) !!}
{!! Form::hidden('alt_id_8', $alt_id_8) !!}
{!! Form::hidden('alt_id_9', $alt_id_9) !!}
{!! Form::hidden('alt_id_10', $alt_id_10) !!}

{!! Form::hidden('alt_string_1', $alt_string_1) !!}
{!! Form::hidden('alt_string_2', $alt_string_2) !!}
{!! Form::hidden('alt_string_3', $alt_string_3) !!}
{!! Form::hidden('alt_string_4', $alt_string_4) !!}
{!! Form::hidden('alt_string_5', $alt_string_5) !!}
{!! Form::hidden('alt_string_6', $alt_string_6) !!}
{!! Form::hidden('alt_string_7', $alt_string_7) !!}
{!! Form::hidden('alt_string_8', $alt_string_8) !!}
{!! Form::hidden('alt_string_9', $alt_string_9) !!}
{!! Form::hidden('alt_string_10', $alt_string_10) !!}
<div class="text-center"> 
    {!! Form::submit('Start Survey', ['class' => 'btn btn-primary', 'id' => 'start_survey']) !!}
</div>

考虑到您在原始问题中提供的详细信息,似乎Laravel在拒绝您提交表格时表现得完全正确。

用户代理正在浏览到http://some.example.com以及CCD_ 7将表单转换为https://laravel.example.com,通过iframe。如果我没有错的话,这正是CSRF令牌设计用来防止的行为。

这个问题甚至可能只是iFrame中Laravel 5 TokenMismatchException的重复。我同意那里公认的答案。

如果这是一个内部站点,并且您愿意承担相关风险,您可以为您要POST的路线添加一个例外,如上面引用的答案所述。

按照这些步骤

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

X-CSRF-TOKEN

除了将CSRF令牌作为POST参数进行检查外,Laravel VerifyCsrfToken中间件还将检查X-CSRF-token请求标头。例如,您可以将令牌存储在"meta"标签中:

一旦创建了元标记,就可以指示像jQuery这样的库将令牌添加到所有请求头中。这为基于AJAX的应用程序提供了简单、方便的CSRF保护:

$.ajaxSetup({标头:{'X-CSRF-TOKEN':$('meta[name="CSRF TOKEN"]').attr('content')}});

X-XSRF-TOKEN

Laravel还将CSRF令牌存储在XSRF-token cookie中。您可以使用cookie值来设置X-XSRF-TOKEN请求标头。一些JavaScript框架,如Angular,会自动为您执行此操作。您不太可能需要手动使用此值。