Laravel 5.1 - 仅 Safari 浏览器上的 iframe 的令牌不匹配问题
Posted
技术标签:
【中文标题】Laravel 5.1 - 仅 Safari 浏览器上的 iframe 的令牌不匹配问题【英文标题】:Laravel 5.1 - Token Mismatch issue with Iframes on Safari Browser Only 【发布时间】:2017-08-21 06:11:48 【问题描述】:我在 laravel 5.1 中创建了几个表单,现在我在另一个使用 IFrame 的站点上使用这些表单。这些表单适用于除 Safari 之外的所有浏览器。当我在填写表格后尝试提交/发布数据时,我收到错误“CSRF 令牌不匹配”,我不知道这里有什么问题,csrf 令牌也在创建和发送。这只发生在 safari 浏览器的情况下。
有人可以指导我如何摆脱这个问题吗?
复制步骤:
创建一个表单,然后通过 IFrame 使用它。提交表单后,会产生 CSRF Token Mismatch 错误。
如何解决这个问题?请帮忙!
代码示例:
<form method="post" action="/step1/$voucher->user_id" accept-charset="UTF-8">
<input name="_method" type="hidden" value="post">
!! csrf_field() !!
<div class="row" style="margin-top:15px; margin-bottom:15px;">
<div class="col-md-4 col-xs-5 hidden">
<input name="voucher_id" type="hidden" value="$voucher->id" id="voucher_id">
<input class="form-control spin text-center qty1" name="qty" id="qty" type="text" value="1" >
<input name="r_full_name" type="hidden" value="" id="r_full_name">
</div>
<div class="col-md-3 col-xs-3">
<button type="submit" class="btn btn-theme"><i class="fa fa-shopping-cart" aria-hidden="true"></i> | BUY</button>
</div>
</form>
这是示例代码...再次,所有这些在任何其他浏览器(FF,Chrome)中都可以完美运行,但是当我将此表单放入另一个站点的 iframe 时,我会收到 TokenMissmatch 错误...
【问题讨论】:
提供一些代码。 我用代码更新...但代码不是问题(在 FF 和 Chrome 中完美运行)只是当我将它放入另一个网站的 iframe 时 - 然后 Safari 浏览器让我成为问题。跨度> 也许你可以重新生成令牌。尝试在父窗口加载时重新加载框架 顺便问一下,为什么用 [javascript] 标记? 您使用的是哪个操作系统? 【参考方案1】:这很可能与 Safari 处理 cookie 和 iframe 的方式有关,请参阅this question 的答案,其中引用了Safari Developer FAQ 的旧版本,其中指出
Safari 附带了一个保守的 cookie 策略,它限制了 cookie 仅写入用户选择(“导航到”)的页面。这 默认的保守策略可能会混淆基于框架的站点尝试 写入 cookie 并失败。
这可以解释为什么你会遇到这个问题。
该问题的第二个答案提出了一个解决方案,可以在here 找到。这与重定向到拥有 cookie 的域、设置会话并重定向回来基本上是一样的,这是提到的另一个解决方案 here。
【讨论】:
【参考方案2】:csrf 令牌是为了防止跨站点请求伪造,这就是您在使用 iFrame 时所做的事情!该令牌可防止随机网站向您的网站提交表单。因此,使用 Laravel 和令牌的表单无法在 iFrame 中工作!
如果您想在其他站点上发布表单,请禁用该表单的 csrf 令牌或以您的方式处理提交请求,以便它根据您的需要通过所有安全检查。
【讨论】:
【参考方案3】:我认为这篇文章可以帮助你,你可以改变你的 cookie 政治。
Csfr token problem
【讨论】:
【参考方案4】:为每个请求发送令牌
$.ajaxSetup(headers: 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') );
【讨论】:
【参考方案5】:测试浏览器是否为 Safari 页面是否为主页且会话未启动,如果是则将窗口顶部 url 重定向到 iframe 父 url
使用重定向在 Safari 上修复 iframe 的 Laravel 令牌不匹配问题的步骤如下:
1) 添加路线
Route::get('/start-session', 'HomeController@startSession');
2) 添加控制器动作
public function startSession()
session()->put('isSessionStarted', true);
return redirect('http://www.iframeparentsite.com'); // redirect to website where iframe is hosted
3) 安装jenssegers/agent
模块检测Safari浏览器https://github.com/jenssegers/agent
composer require jenssegers/agent
4) 在控制器中使用它
use Jenssegers\Agent\Agent;
5) 通过isSafari
、isHomepage
和isSessionStarted
在主页控制器操作中查看
public function index()
$agent = new Agent();
$this->data['isSafari'] = $agent->is('Safari') && !$agent->is('Chrome');
$this->data['isHomepage'] = true;
$this->data['isSessionStarted'] = session()->get('isSessionStarted');
return view('home', $this->data);
6) 在页面布局head部分添加blade/javascript代码
@if ($isSafari && !empty($isHomepage) && empty($isSessionStarted))
window.top.location = " url('/start-session') ";
@endif
重定向将在主页上发生一次,需要 1/2 秒
【讨论】:
以上是关于Laravel 5.1 - 仅 Safari 浏览器上的 iframe 的令牌不匹配问题的主要内容,如果未能解决你的问题,请参考以下文章
我的4S是IOS 5.1版本 可是我上工商银行网上银行显示需要Safari5.1或以上版本`难道我的机子不是吗?求解?
HTML 5 音频、视频不工作 Safari 5.1 WinXP
VerifyCsrfToken.php 第 53 行中的 TokenMismatchException:(Firefox 浏览器)在 laravel 5.1 中?