我有一个在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,会自动为您执行此操作。您不太可能需要手动使用此值。