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...
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...
Share Improve this question edited Mar 28, 2017 at 9:07 Aleks Per asked Mar 28, 2017 at 8:56 Aleks PerAleks Per 1,6397 gold badges38 silver badges74 bronze badges 7- provide us some code. – Md. Sahadat Hossain Commented Mar 28, 2017 at 9:04
- 1 I update with code ... but code is not a problem (works perfect in FF and Chrome) just when I put it into iframe in another website - then Safari browser makes me a problem. – Aleks Per Commented Mar 28, 2017 at 9:08
- 1 Maybe you could regenerate token. Try to reload frame on parent window load – Alex Slipknot Commented Mar 30, 2017 at 11:57
- By the way, why is this tagged with [javascript] ? – Uberswe Commented Mar 30, 2017 at 22:36
- Which operating system you are using ? – Niklesh Raut Commented Apr 1, 2017 at 3:08
5 Answers
Reset to default 6 +25This 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.
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.
I think this post can help you, You can change your cookie politics.
Csfr token problem
send token for each request
$.ajaxSetup({headers: {'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') } });
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.'); // redirect to website where iframe is hosted
}
3) Install jenssegers/agent
module to detect Safari browser https://github./jenssegers/agent
poser 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