Я создал несколько форм в laravel 5.1, теперь я использую эти формы на другом сайте, используя IFrame. Эти формы работают во всех браузерах, кроме Safari. Когда я пытаюсь отправить / отправить данные после заполнения форм, я получаю сообщение об ошибке «CSMF Token Mismatch», я не знаю, что здесь проблема, токен csrf также создается и отправляется. Это происходит только в случае браузера Safari.
Может ли кто-нибудь мне посоветовать, как я могу избавиться от этой проблемы?
Действия по воспроизведению:
создайте форму, а затем используйте ее через IFrame. после отправки формы возникает ошибка несоответствия токена CSRF.
Как это решить? Пожалуйста помоги!
ОБРАЗЕЦ КОДА:
<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>
это пример кода … AGAIN все это прекрасно работает в любом другом браузере (FF, Chrome), но когда я помещаю эти формы в iframe на другом сайте, то получаю ошибку TokenMissmatch …
Скорее всего, это связано с тем, как Safari обрабатывает файлы cookie и iframes, см. Ответ на этот вопрос, который цитирует то, что похоже на старую версию FAQ Safari Developer, в которой говорится
Safari поставляется с консервативной политикой cookie, которая ограничивает запись файлов cookie только выбранными страницами («ориентирована на») пользователем. Эта консервативная политика по умолчанию может запутать сайты на основе фреймов, которые пытаются писать файлы cookie и терпят неудачу.
Это объясняет, почему у вас возникают проблемы с этим.
Второй ответ на этот вопрос предлагает решение, которое можно найти здесь . Это в основном то же самое, что и перенаправление на домен, которому принадлежат файлы cookie, настройка сеанса и перенаправление обратно, что является другим решением, которое упоминается здесь .
Символ csrf предназначен для предотвращения подделки подпрограммы сайта, и это то, что вы делаете, когда используете iFrame! Токен предотвращает отправку случайных веб-сайтов на ваш сайт. Таким образом, форма, использующая Laravel и токен, не будет работать в iFrame!
Если вы хотите опубликовать форму на другом сайте, либо отключите токен csrf для этой формы, либо обработайте запрос на отправку таким образом, чтобы он прошел всю проверку безопасности в соответствии с вашими потребностями.
Я думаю, что этот пост может вам помочь, вы можете изменить свою политику в отношении файлов cookie.
Проблема маркера Csfr
отправлять токен для каждого запроса
$.ajaxSetup({headers: {'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') } });
Проверьте, является ли браузер Safari, а страница – домашняя страница, а сеанс не запущен. Если да, то перенаправляйте верхний URL-адрес окна в исходный URL-адрес iframe.
Шаги по исправлению проблемы несоответствия маркера Laravel с iframe в Safari с использованием перенаправления:
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) Pass 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) Добавить код лезвия / javascript в разделе макета страницы
@if ($isSafari && !empty($isHomepage) && empty($isSessionStarted)) window.top.location = "{{ url('/start-session') }}"; @endif
Перенаправление произойдет один раз на главной странице и займет 1/2 секунды