Reputation: 1639
I have created few forms in laravel 5.1, now i am using those forms on another site using IFrame. Those forms works in all browsers except Safari. When i try to submit/post data after filling up forms, i get error "CSRF Token Mismatch", I dont know what the issue here, csrf token is also being created and sent. This is only happening in case of safari browser.
Can someone guide me that how i can get rid of this issue??
Steps To Reproduce:
create a form and then use it via IFrame. after form is submitted, CSRF Token Mismatch error is generated.
How to solve this? Please help!
CODE SAMPLE:
<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>
this is sample code... AGAIN all this works perfect in any other browser (FF, Chrome) but when I put this forms into iframe in another site then I get TokenMissmatch error...
Upvotes: 8
Views: 4999
Reputation: 6612
Test if browser is Safari and page is home page and session is not started, If yes then redirect window top url to iframe parent url
Steps to fix Laravel Token Mismatch issue with iframe on Safari using redirect is as below:
1) Add route
Route::get('/start-session', 'HomeController@startSession');
2) Add controller action
public function startSession() {
session()->put('isSessionStarted', true);
return redirect('http://www.iframeparentsite.com'); // redirect to website where iframe is hosted
}
3) Install jenssegers/agent
module to detect Safari browser https://github.com/jenssegers/agent
composer require jenssegers/agent
4) Use it in controller
use Jenssegers\Agent\Agent;
5) Pass isSafari
, isHomepage
and isSessionStarted
to view in homepage controller action
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) Add blade/javascript code in page layout head section
@if ($isSafari && !empty($isHomepage) && empty($isSessionStarted))
window.top.location = "{{ url('/start-session') }}";
@endif
Redirect will happen once on homepage and will take 1/2 seconds
Upvotes: 0
Reputation: 492
send token for each request
$.ajaxSetup({headers: {'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') } });
Upvotes: 0
Reputation: 1731
I think this post can help you, You can change your cookie politics.
Upvotes: 0
Reputation: 653
The csrf token is to prevent cross site request forgery and that's what you are doing when you use an iFrame! The token prevents random websites from submitting a form to your site. So a form using Laravel and a token is not going to work in an iFrame!
If you want to publish the form on other site, either disable the csrf token for that form or handle the submit request in your way so that it pass all the security check according to your need.
Upvotes: 4
Reputation: 1058
This is most likely related to how Safari handles cookies and iframes, please see the answer from this question which quotes what seems like an older version of the Safari Developer FAQ which states
Safari ships with a conservative cookie policy which limits cookie writes to only the pages chosen ("navigated to") by the user. This default conservative policy may confuse frame based sites that attempt to write cookies and fail.
That would explain why you are having trouble with this.
The second answer to that question proposes a solution which can be found here. This is basically the same thing as doing a redirect to the domain that owns the cookies, setting the session and redirecting back, which is another solution which is mentioned here.
Upvotes: 6