【问题标题】:Laravel TokenMismatchExpection when posting from inside an iframe从 iframe 内部发布时 Laravel TokenMismatchException
【发布时间】:2016-01-08 00:19:35
【问题描述】:

我有一个在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\MiddlewareVerifyCsrfToken 类并添加了 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>

【问题讨论】:

  • 尝试将&lt;input name="_token" type="hidden" value="Dk6SN4WzO4brbvdnBO6JZ7e1lBGjmYz8GQJ1lYFo"&gt; 更改为{{ csrf_field() }}
  • @maiorano84 我正在使用 {{ csrf_field() }}。
  • 你能在 iframe 内外都转储请求,看看有什么不匹配的吗?
  • 真的吗?因为我在您的代码中的任何地方都看不到它。发布模板的实际内容,而不仅仅是 HTML 输出。
  • @maiorano84 我明天离开办公室时将发布模板。我正在使用 Form 外观来​​执行此操作,因此它是自动的

标签: php laravel laravel-5 laravel-5.1 laravel-5.2


【解决方案1】:

鉴于您在原始问题中提供的详细信息,似乎 Laravel 在拒绝允许您提交表单时表现得完全正确。

用户代理正在通过 iframe 浏览到 http://some.example.comPOST 将表单发送到 https://laravel.example.com。如果我没记错的话,这正是 CSRF 令牌旨在防止的行为。

这个问题甚至可能与 Laravel 5 TokenMismatchException only in iFrame 重复。我同意那里接受的答案。

如果这是一个内部站点并且您愿意接受相关风险,您可以为您所在的路由添加一个例外POSTing,如上面引用的答案中所述。

【讨论】:

    【解决方案2】:

    按此步骤操作

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

    X-CSRF-TOKEN

    除了检查 CSRF 令牌作为 POST 参数,Laravel VerifyCsrfToken 中间件还会检查 X-CSRF-TOKEN 请求头。例如,您可以将令牌存储在“元”标签中:

    创建元标记后,您可以指示 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,会自动为您执行此操作。您不太可能需要手动使用此值。

    【讨论】:

    • 我没有使用任何 Ajax/JS 请求。我正在提交一个简单的表格。当表单不在 iframe 中时,它可以正常工作。当我将它放在不同域的 iframe 中时,就会出现问题。请记住,表单和表单请求处理程序都在 laravel 应用程序上
    • @MikeA ,我从这里浏览了详细的文档。 pipwerks.com/2008/11/30/… 等,您必须手动通过 AJAX 传递该令牌值。所以,它会验证这个令牌。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    • 2020-12-15
    • 2015-10-04
    • 2015-02-24
    • 1970-01-01
    • 2016-03-06
    相关资源
    最近更新 更多