Aleks Per
Aleks Per

Reputation: 1639

Laravel 5.1 - Token Mismatch issue with Iframes on Safari Browser Only

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

Answers (5)

Manoj Yadav
Manoj Yadav

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

iMezied
iMezied

Reputation: 492

send token for each request

$.ajaxSetup({headers: {'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')  } });

Upvotes: 0

Vahe Galstyan
Vahe Galstyan

Reputation: 1731

I think this post can help you, You can change your cookie politics.

Csfr token problem

Upvotes: 0

rajatsaurastri
rajatsaurastri

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

Uberswe
Uberswe

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

Related Questions