Уловка с iframe сторонних файлов cookie в Safari больше не работает?

138

Итак, это уже десятая месть за вопрос «как заставить сторонние файлы cookie работать в Safari», но я спрашиваю снова, потому что думаю, что игровое поле изменилось, возможно, после февраля 2012 года. Один из стандартных трюков для получения третьего партийные файлы cookie в Safari были следующими: использовать некоторый javascript для POST в скрытый iframe. Он (раньше) заставлял Safari думать, что пользователь взаимодействовал со сторонним контентом, а затем разрешать установку файлов cookie.

Я думаю, что эта лазейка была закрыта после небольшого скандала, когда выяснилось, что Google использовал этот трюк со своей рекламой. По крайней мере, при использовании этого трюка я полностью не смог установить файлы cookie в Safari. Я обнаружил несколько случайных сообщений в Интернете, в которых утверждалось, что Apple работает над закрытием лазейки, но я не нашел ни одного официального сообщения.

В качестве запасного варианта я даже попытался переработать основной сторонний фрейм, чтобы вам приходилось нажимать кнопку до загрузки контента, но даже такого уровня прямого взаимодействия было недостаточно, чтобы растопить холодное холодное сердце Safari.

Так кто-нибудь знает наверняка, действительно ли Safari закрыл эту лазейку? Если да, существуют ли другие обходные пути (кроме ручного включения идентификатора сеанса в каждый запрос)?

GS Hurley
источник
23
Использование IFRAME третьей стороны , которая нуждается в куках, конечно , не по определению атака безопасности! У нас есть интернет-магазин, который используется в iframe на множестве разных доменов, и в последнее время у нас возникают всевозможные проблемы с Safari, поэтому меня также очень интересует ответ на этот (законный) вопрос.
mscha
14
Практически каждый, кто создает приложения для Facebook, сталкивается с этой проблемой с Safari. Приложения Facebook работают в iframe, и все они по определению принадлежат сторонним разработчикам. Вот почему поддержка Safari в приложениях Facebook немного нестабильна: вы не можете использовать файлы cookie.
GS Hurley
Я не могу воспроизвести эту проблему в Safari 5.1.7. Он принимает файлы cookie из iframe моего приложения facebook с настройкой по умолчанию «без сторонних файлов cookie». Однако Chrome 19.0.1084.46 с той же настройкой блокирует cookie.
Евгений Шадчнев
4
Chrome 19+ с установленным (к счастью) нестандартным по умолчанию параметром «Блокировать сторонние файлы cookie и данные сайта» является (даже более жестким), чем параметр Safari по умолчанию «Блокировать файлы cookie от третьих лиц и рекламодателей». В Chrome, даже если вы посещаете сторонний домен и устанавливаете файлы cookie, они не будут передаваться в iframe. Пользователь должен фактически добавить «исключение» для вашего домена в свои настройки безопасности Chrome.
Аарон Гибральтер 01
Что вы имеете в виду под февралем 2012 года? Есть ли технические изменения в Safari или изменения в законодательстве?
жидкость

Ответы:

51

Просто хотел оставить здесь простое рабочее решение, не требующее взаимодействия с пользователем .

Как я сказал в сообщении, которое я сделал :

По сути, все, что вам нужно сделать, это загрузить свою страницу в top.location, создать сеанс и перенаправить его обратно в facebook.

Добавьте этот код вверху страницы index.phpи установите его $page_urlдля конечной вкладки / URL-адреса приложения, и вы увидите, что ваше приложение будет работать без проблем.

<?php
    // START SAFARI SESSION FIX
    session_start();
    $page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
    if (isset($_GET["start_session"]))
        die(header("Location:" . $page_url));

    if (!isset($_GET["sid"]))
        die(header("Location:?sid=" . session_id()));
    $sid = session_id();
    if (empty($sid) || $_GET["sid"] != $sid):
?>
   <script>
        top.window.location="?start_session=true";
    </script>
<?php
    endif;
    // END SAFARI SESSION FIX
?>

Примечание: это было сделано для facebook, но на самом деле это будет работать в любых других подобных ситуациях.


Изменить 20 декабря 2012 г. - Сохранение подписанного запроса:

Приведенный выше код не поддерживает данные отправки запросов, и вы потеряете signed_request, если ваше приложение полагается на подписанный запрос, не стесняйтесь попробовать следующий код:

Примечание: он все еще проходит надлежащее тестирование и может быть менее стабильным, чем первая версия. Используйте на свой страх и риск / обратная связь приветствуется.

(Спасибо CBroe за то, что указали мне правильное направление, что позволило улучшить решение)

// Start Session Fix
session_start();
$page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
if (isset($_GET["start_session"]))
    die(header("Location:" . $page_url));
$sid = session_id();
if (!isset($_GET["sid"]))
{
    if(isset($_POST["signed_request"]))
       $_SESSION["signed_request"] = $_POST["signed_request"];
    die(header("Location:?sid=" . $sid));
}
if (empty($sid) || $_GET["sid"] != $sid)
    die('<script>top.window.location="?start_session=true";</script>');
// End Session Fix
Диого Раминос
источник
Спасибо, работает как шарм, и его так легко реализовать в существующих приложениях :-)
SamiSalami
Итак, этот в основном работает с парой перенаправлений, верно?
Аарон Гибральтер 01
1
@hugoderhungrige, пожалуйста, я только что добавил новую версию, не стесняйтесь проверить ее, если вам нужно поддерживать подписанный запрос в ваших приложениях.
Диого Раминхос
1
@CBroe Большое спасибо, что указали на это! Вы были правы, это работает, так как по второму запросу у пользователя уже запущена сессия! Я предполагаю, что «худший слепой - тот, кто не хочет видеть».
Diogo Raminhos
1
@Whiteagle Можете ли вы предоставить тестовый пример, демонстрирующий 1 и 2?
Gajus
35

Вы сказали, что хотите, чтобы ваши пользователи нажимали кнопку перед загрузкой контента. Мое решение заключалось в том, чтобы кнопка открывала новое окно браузера. Это окно устанавливает файл cookie для моего домена, обновляет средство открытия и затем закрывается.

Итак, ваш основной сценарий может выглядеть так:

<?php if(count($_COOKIE) > 0): ?>
<!--Main Content Stuff-->
<?php else: ?>
<a href="/safari_cookie_fix.php" target="_blank">Click here to load content</a>
<?php endif ?>

Тогда safari_cookie_fix.php выглядит так:

<?php
setcookie("safari_test", "1");
?>
<html>
    <head>
        <title>Safari Fix</title>
        <script type="text/javascript" src="/libraries/prototype.min.js"></script>
    </head>
    <body>
    <script type="text/javascript">
    document.observe('dom:loaded', function(){
        window.opener.location.reload();
        window.close();
    })
    </script>
    This window should close automatically
    </body>
</html>
Дрюричардс
источник
Я думал о чем-то подобном. Работает безупречно. Загружаю его вместе с диалогом разрешений. Благодарность!
vwoelm
Похоже, что это также работает с настройками Safari, и, как только это станет общеизвестным, будет прекращено, как и другие «решения». Я ищу совершенно другое решение, потому что становится довольно очевидным, что сторонние файлы cookie теперь являются дьяволом, даже если они используются надлежащим образом.
LocalPCGuy
1
Это решение сработало для меня, однако необходимо ли всплывающее окно? Не могли бы вы перенаправить свой iframe на страницу сафари, установить cookie, а затем перенаправить обратно в игру с заголовками перенаправления? Или вам нужно всплывающее окно, чтобы у пользователя была какая-то форма прямого контакта с сервером?
Энтони Гастингс,
это сработало; к счастью, нажатие кнопки для инициализации не имело большого значения в моем приложении.
Littlered
@LocalPCGuy Я не уверен, что он будет заблокирован, как другие решения, потому что он требует, чтобы пользователь действительно щелкал / взаимодействовал со страницей, чтобы всплывающее окно не блокировалось. Решение, предложенное Safari, похоже, работает хорошо: рекламодатели не смогут тайно устанавливать междоменные файлы cookie, а встроенные приложения потребуют от пользователя взаимодействия, прежде чем он сможет установить файл cookie.
Аарон Гибральтер 01
15

Я обманул Safari с помощью .htaccess:

#http://www.w3.org/P3P/validator.html
<IfModule mod_headers.c>
Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"NOI DSP COR NID CUR ADM DEV OUR BUS\""
Header set Set-Cookie "test_cookie=1"
</IfModule>

И у меня тоже перестало работать. Все мои приложения теряют сеанс в Safari и перенаправляются из Facebook. Поскольку я очень спешу исправить эти приложения, в настоящее время я ищу решение. Я буду держать вас в курсе.

Изменить (2012-04-06): Судя по всему, Apple "исправила" это с помощью 5.1.4. Я уверен, что это реакция на Google: «Существовала проблема с применением политики использования файлов cookie. Сторонние веб-сайты могли устанавливать файлы cookie, если для параметра« Блокировать файлы cookie »в Safari было установлено значение по умолчанию« От третьих лиц и рекламодателей ». Http://support.apple.com/kb/HT5190

vwoelm
источник
1
Видимо Apple "исправила" это в 5.1.4. Я уверен, что это реакция на Google: «Существовала проблема с применением политики использования файлов cookie. Сторонние веб-сайты могли устанавливать файлы cookie, если для параметра« Блокировать файлы cookie »в Safari было установлено значение по умолчанию« От третьих лиц и рекламодателей». support.apple.com/kb/HT5190
vwoelm
1
Поэтому я думаю, что этот комментарий vwoelm является наиболее близким к ответу, который я искал. Прежде всего, я хотел подтвердить, что Apple окончательно закрыла лазейку, и ссылка на статью поддержки Apple - это просто так. Вторая часть моего вопроса все еще актуальна. Каков диапазон вариантов обходных путей. Ясно, что мы можем кодировать идентификаторы сеанса как параметры GET / POST, но каковы другие варианты. Работает ли в этом контексте локальное хранилище? Флэш-куки?
GS Hurley 06
@vwoelm: это действительно ответ, который я искал (но не надеялся). Если вы поместите это в ответ вместо комментария, я назначу вам награду.
mscha 06
3
@gshurley Я думаю, что отправка идентификаторов сеансов через параметры GET / POST - единственный вариант. Это небезопасно, но опять же Facebook вынуждает нас обслуживать холст-приложения без SSL. И кроме того, что вы действительно получаете, взламывая приложение Facebook, ха-ха? Мы находимся во власти Apple, и они в настоящее время находятся в жестоком режиме.
hekevintran
14

В вашем контроллере Ruby on Rails вы можете использовать:

private

before_filter :safari_cookie_fix

def safari_cookie_fix
  user_agent = UserAgent.parse(request.user_agent) # Uses useragent gem!
  if user_agent.browser == 'Safari' # we apply the fix..
    return if session[:safari_cookie_fixed] # it is already fixed.. continue
    if params[:safari_cookie_fix].present? # we should be top window and able to set cookies.. so fix the issue :)
      session[:safari_cookie_fixed] = true
      redirect_to params[:return_to]
    else
      # Redirect the top frame to your server..
      render :text => "<script>alert('start redirect');top.window.location='?safari_cookie_fix=true&return_to=#{set_your_return_url}';</script>"
    end
  end
end
шутить
источник
Есть ли аналогичная проблема с сессиями в сафари?
Новичок в Rails
вы можете заменить set_your_return_url на request.env ['HTTP_REFERER'], поскольку мы находимся внутри iframe :-D
Люк Боассай
Я пробовал это решение, и единственная проблема заключается в том, что я не могу вернуться к родительскому URL-адресу iframe. Есть ли в Rails метод для получения URL-адреса родительского iframe? спасибо
idejuan
Это заняло у меня время, но, наконец, я понял, что самый простой способ (TMO) - просто добавить его в качестве параметра строки запроса в URL-адрес перенаправления приложения rails. Нежный и чистый.
guyaloni
1
Этот ответ создает открытый перенаправитель, что является распространенной проблемой безопасности. Опасный код есть redirect_to params[:return_to]. Этот параметр необходимо сравнить с белым списком безопасных мест для перенаправления. См. Owasp.org/index.php/…
phylae
13

Для моей конкретной ситуации я решил проблему, используя window.postMessage () и исключив любое взаимодействие с пользователем. Обратите внимание, что это будет работать только в том случае, если вы можете каким-то образом выполнить js в родительском окне. Либо включив js из вашего домена, либо если у вас есть прямой доступ к источнику.

В iframe (домен-b) я проверяю наличие файла cookie, и, если он не установлен, отправляю postMessage родительскому (домен-a). Например;

if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1
    && document.cookie.indexOf("safari_cookie_fix") < 0) {
    window.parent.postMessage(JSON.stringify({ event: "safariCookieFix", data: {} }));
}

Затем в родительском окне (домен-а) прослушайте событие.

if (typeof window.addEventListener !== "undefined") {
    window.addEventListener("message", messageReceived, false);
}

function messageReceived (e) {
    var data;

    if (e.origin !== "http://www.domain-b.com") {
        return;
    }

    try {
        data = JSON.parse(e.data);
    }
    catch (err) {
        return;
    }

    if (typeof data !== "object" || typeof data.event !== "string" || typeof data.data === "undefined") {
        return;
    }

    if (data.event === "safariCookieFix") {
        window.location.href = e.origin + "/safari/cookiefix"; // Or whatever your url is
        return;
    }
}

Наконец, на своем сервере (http://www.domain-b.com/safari/cookiefix) вы устанавливаете cookie и перенаправляете обратно туда, откуда пришел пользователь. Пример ниже использует ASP.NET MVC

public class SafariController : Controller
{
    [HttpGet]
    public ActionResult CookieFix()
    {
        Response.Cookies.Add(new HttpCookie("safari_cookie_fix", "1"));

        return Redirect(Request.UrlReferrer != null ? Request.UrlReferrer.OriginalString : "http://www.domain-a.com/");
    }

}
Фрэнк
источник
Вы не получаете синтаксическую ошибку при вызове postMessage?
akousmata
Нужно добавить второй параметр , "*"чтобы PostMessageисправить ошибку синтаксиса
Michael Baldry
Хотел бы я дать этому ответу больше голосов. Это самый простой и правильный способ решить эту проблему. Спасибо, что разместили!
AaronP
9

У меня была такая же проблема, и сегодня я нашел исправление, которое мне подходит. Если пользовательский агент содержит Safariфайлы cookie и не настроены, я перенаправляю пользователя в диалог OAuth:

<?php if ( ! count($_COOKIE) > 0 && strpos($_SERVER['HTTP_USER_AGENT'], 'Safari')) { ?>
<script type="text/javascript">
    window.top.location.href = 'https://www.facebook.com/dialog/oauth/?client_id=APP_ID&redirect_uri=MY_TAB_URL&scope=SCOPE';
</script>
<?php } ?>

После аутентификации и запроса разрешений диалог OAuth будет перенаправлен на мой URI в верхнем расположении. Таким образом, установка файлов cookie возможна. Для всех наших приложений с холстом и вкладками страниц я уже включил следующий скрипт:

<script type="text/javascript">
    if (top.location.href==location.href) top.location.href = 'MY_TAB_URL';
</script>

Таким образом, пользователь будет снова перенаправлен на вкладку страницы Facebook с уже установленным действительным файлом cookie, и подписанный запрос будет отправлен снова.

Саша Галлея
источник
Отличная работа над этим. Я обновил проверку пользовательского агента, чтобы убедиться, что Chrome также не был в пользовательском агенте, поскольку в Chrome также есть Safari в строке пользовательского агента. Перенаправление на страницу вашего домена, установка необходимых файлов cookie / запуск сеанса, а затем перенаправление обратно в ваше приложение на apps.facebook.com сработали как шарм. Кажется глупым, но работает хорошо. Спасибо Саше за подсказку!
Майк
7

В конце концов я выбрал решение, аналогичное тому, которое предоставил Sascha, но с небольшой корректировкой, поскольку я явно устанавливаю файлы cookie в PHP:

// excecute this code if user has not authorized the application yet
// $facebook object must have been created before

$accessToken = $_COOKIE['access_token']

if ( empty($accessToken) && strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') ) {

    $accessToken = $facebook->getAccessToken();
    $redirectUri = 'https://URL_WHERE_APP_IS_LOCATED?access_token=' . $accessToken;

} else {

    $redirectUri = 'https://apps.facebook.com/APP_NAMESPACE/';

}

// generate link to auth dialog
$linkToOauthDialog = $facebook->getLoginUrl(
    array(
        'scope'         =>  SCOPE_PARAMS,
        'redirect_uri'  =>  $redirectUri
    )
);

echo '<script>window.top.location.href="' . $linkToOauthDialog . '";</script>';

Это проверяет, доступен ли cookie в браузере сафари. На следующем этапе мы находимся в домене приложения, а именно в URI, указанном как URL_WHERE_APP_IS_LOCATED выше.

if (isset($_GET['accessToken'])) {

    // cookie has a lifetime of only 10 seconds, so that after
    // authorization it will disappear
    setcookie("access_token", $_GET['accessToken'], 10); 

} else {

  // depending on your application specific requirements
  // redirect, call or execute authorization code again
  // with the cookie now set, this should return FB Graph results

}

Итак, после перенаправления в домен приложения файл cookie устанавливается явно, и я перенаправляю пользователя в процесс авторизации.

В моем случае (поскольку я использую CakePHP, но он должен нормально работать с любой другой инфраструктурой MVC) я снова вызываю действие входа в систему, когда авторизация FB выполняется в другой раз, и на этот раз это удается из-за существующего файла cookie.

После авторизации приложения у меня больше не было проблем с использованием приложения с Safari (5.1.6)

Надеюсь, это может кому-нибудь помочь.

Марсель Калверам
источник
1
это сработало для меня !! Благодарность!! .. у меня была эта проблема с Safari 5.1.7 .... теперь она решена!
Khalizar
5

У меня была эта проблема на устройствах под управлением iOS. Я сделал магазин, который можно встраивать в обычный веб-сайт с помощью iframe. Каким-то образом при каждой загрузке страницы пользователь получал новый идентификатор сеанса, в результате чего пользователи застревали на полпути процесса, потому что некоторые значения не присутствовали в сеансе.

Я пробовал некоторые решения, приведенные на этой странице, но всплывающие окна не очень хорошо работают на iPad, и мне нужно было самое прозрачное решение.

Я решил это с помощью перенаправления. Веб-сайт, на котором встроен мой сайт, должен сначала перенаправить пользователя на мой сайт, поэтому верхний фрейм содержит URL-адрес моего сайта, где я устанавливаю файл cookie и перенаправляю пользователя на соответствующую страницу на веб-сайте, который встраивает мой сайт, который передается через в URL.

Пример кода PHP

Удаленный веб-сайт перенаправляет пользователя на

http://clientname.example.com/init.php?redir=http://www.domain.com/shop/frame

init.php

<?php
// set a cookie for a year
setcookie('initialized','1',time() + 3600 * 24 * 365, '/', '.domain.com', false, false);
header('location: ' . $_GET['redir']);
die;

Пользователь попадает туда, http://www.domain.com/shop/frameкуда встроен мой сайт, сохраняя сеансы должным образом и поедая файлы cookie.

Надеюсь, это кому-то поможет.

ar34z
источник
3

Позвольте мне поделиться своим исправлением в ASP.NET MVC 4. Основная идея как в правильном ответе для PHP. Следующий код добавлен в основной макет в заголовке возле раздела скриптов:

@if (Request.Browser.Browser=="Safari")
{
    string pageUrl = Request.Url.GetLeftPart(UriPartial.Path);
    if (Request.Params["safarifix"] != null && Request.Params["safarifix"] == "doSafariFix")
    {
        Session["IsActiveSession"] = true;
        Response.Redirect(pageUrl);
        Response.End();
    }
        else if(Session["IsActiveSession"]==null)
    {
        <script>top.window.location = "?safarifix=doSafariFix";</script>
    }
}
Яра
источник
3

Это решение применимо в некоторых случаях - если возможно:

Если страница содержимого iframe использует поддомен страницы, содержащей iframe, файл cookie больше не блокируется.

чудо
источник
Это полезная информация - именно то, что я искал. Хотя я уверен, что большинство людей не могут менять домены, я собираюсь это сделать. Попросите сайт, в который я встраиваю, создать поддомен <mycompany>. <theircompany> .com, который сопоставляется с моим IP-адресом и VHost на моей стороне для этого домена, и использовать этот URL-адрес в iFrame. Сложно, но должно быть пуленепробиваемым.
Elocution Safari,
1
Это может усложниться, если вы используете https с поддоменом, поскольку серверу поддомена потребуется сертификат SSL для соответствия.
Роджер Халлибертон
1

Google действительно выпустил кошку из мешка на этом. Некоторое время они использовали его для доступа к файлам cookie отслеживания. Почти сразу это было исправлено Apple = \

оригинальный пост Wall Street Journal

Колин Годси
источник
Я знаю о Google, но я ничего не видел, чтобы Apple «исправляла» это (и ломала половину интернета). У вас есть какие-нибудь подробности по этому поводу?
mscha 05
1

Вот код, который я использую. Я обнаружил, что если я устанавливаю какой-либо файл cookie со своего сайта, с этого момента файлы cookie волшебным образом работают в iframe.

http://developocialapps.com/foundations-of-a-facebook-app-framework/

 if (isset($_GET['setdefaultcookie'])) {
        // top level page, set default cookie then redirect back to canvas page
        setcookie ('default',"1",0,"/");
        $url = substr($_SERVER['REQUEST_URI'],strrpos($_SERVER['REQUEST_URI'],"/")+1);
        $url = str_replace("setdefaultcookie","defaultcookieset",$url);
        $url = $facebookapp->getCanvasUrl($url);
        echo "<html>\n<body>\n<script>\ntop.location.href='".$url."';\n</script></body></html>";
        exit();
    } else if ((!isset($_COOKIE['default'])) && (!isset($_GET['defaultcookieset']))) {
        // no default cookie, so we need to redirect to top level and set
        $url = $_SERVER['REQUEST_URI'];
        if (strpos($url,"?") === false) $url .= "?";
        else $url .= "&";
        $url .= "setdefaultcookie=1";
        echo "<html>\n<body>\n<script>\ntop.location.href='".$url."';\n</script></body></html>";
        exit();
    }
Том Кинкейд
источник
1

Немного упрощенная версия на PHP того, что опубликовали другие:

if (!isset($_COOKIE, $_COOKIE['PHPSESSID'])) {
    print '<script>top.window.location="https://example.com/?start_session=true";</script>';
    exit();
}

if (isset($_GET['start_session'])) {
    header("Location: https://apps.facebook.com/YOUR_APP_ID/");
    exit();
}
Чарли Шлиссер
источник
1

Я нашел идеальный ответ на этот вопрос, и все благодаря парню по имени Аллан, который заслуживает здесь всей благодарности. ( http://www.allannienhuis.com/archives/2013/11/03/blocked-3rd-party-session-cookies-in-iframes/ )

Его решение простое и понятное.

На сервере содержимого iframe (домен 2) добавьте файл startsession.php на уровне корневого домена, который содержит:

<?php
// startsession.php
session_start();
$_SESSION['ensure_session'] = true;
die(header('location: '.$_GET['return']));

Теперь на веб-сайте верхнего уровня, содержащем iframe (domain1), вызов страницы, содержащей iframe, должен выглядеть так:

<a href="https://domain2/startsession.php?return=http://domain1/pageWithiFrame.html">page with iFrame</a>

Вот и все! Просто :)

Причина, по которой это работает, заключается в том, что вы направляете браузер на сторонний URL-адрес и тем самым говорите ему доверять ему перед отображением содержимого из него в iframe.

пользователь1351772
источник
0

Я использовал модифицированный (добавленный параметр signed_request к ссылке) трюк Whiteagle, и он работал нормально для сафари, но IE в этом случае постоянно обновляет страницу. Итак, мое решение для сафари и Internet Explorer:

$fbapplink = 'https://apps.facebook.com/[appnamespace]/';
$isms = stripos($_SERVER['HTTP_USER_AGENT'], 'msie') !== false;

// safari fix
if(! $isms  && !isset($_SESSION['signed_request'])) {

    if (isset($_GET["start_session"])) {
        $_SESSION['signed_request'] = $_GET['signed_request'];
        die(header("Location:" . $fbapplink ));

    }
    if (!isset($_GET["sid"])) {
        die(header("Location:?sid=" . session_id() . '&signed_request='.$_REQUEST['signed_request']));
    }
    $sid = session_id();
    if (empty($sid) || $_GET["sid"] != $sid) {
    ?>
    <script>
        top.window.location="?start_session=true";
    </script>
    <?php
    exit;
    }
}

// IE fix
header('P3P: CP="CAO PSA OUR"');
header('P3P: CP="HONK"');


.. later in the code

$sr = $_REQUEST['signed_request'];
if($sr) {
        $_SESSION['signed_request'] = $sr;
} else {
        $sr = $_SESSION['signed_request'];
}
Котко
источник
0

Я также страдал от этой проблемы, но, наконец, получил решение. Первоначально напрямую загружайте URL-адрес iframe в браузере, как небольшое всплывающее окно, а затем обращайтесь только к значениям сеанса внутри iframe.

Картик Кейан
источник
0

Safari теперь блокирует все сторонние файлы cookie. Вы можете использовать API хранилища только для того, чтобы попытаться получить доступ пользователей к их сторонним файлам cookie.

https://www.infoq.com/news/2020/04/safari-third-party-cookies-block/

Майк Флинн
источник
0

Некоторый контекст, который я не видел четко изложенного в существующих ответах (а также многое изменилось с 2012 года!):

Если вы можете управлять как сторонним iframe, так и родительской страницей (т. Е. Вы можете вставить JavaScript на родительскую страницу), тогда доступно несколько обходных путей. Я бы предположил, что наиболее элегантным из них является использование API postMessage, как описано в ответе @Frank, поскольку а) это не требует перенаправления и б) не требует взаимодействия с пользователем.

Если вы НЕ контролируете как сторонний iframe, так и родительскую страницу , например, у вас есть виджет, размещенный на сайте, который вы не контролируете, то большинство ответов, размещенных здесь, не будут работать в Safari с мая 2020 года и перестанут работать в Chrome около 2022 года . То есть, если пользователь уже не посещал ваш домен или не взаимодействовал с iframe, вы не можете устанавливать файлы cookie. Однако есть некоторые коммерческие службы, предлагающие решения этой проблемы, например CloudCookie.io.

AllTheCodez
источник
-1

Недавно я столкнулся с той же проблемой в Safari. Решение, которое я придумал, основано на HTML5 API локального хранилища. Используя локальное хранилище, вы можете эмулировать файлы cookie.

Вот мое сообщение в блоге с подробностями: http://log.scalemotion.com/2012/10/how-to-trick-safari-and-set-3rd-party.html

Владимир Климонтович
источник
Снимок из weabrchive: web.archive.org/web/20121124020234/http://log.scalemotion.com/…
podvzbzdnul
-2

Я решил полностью избавиться от $_SESSIONпеременной и написал обертку вокруг кэша памяти, чтобы имитировать сеанс.

Проверьте https://github.com/manpreetssethi/utils/blob/master/Session_manager.php

Пример использования: в тот момент, когда пользователь заходит в приложение, сохраните подписанный запрос с помощью Session_manager, и, поскольку он находится в кеше, вы можете получить к нему доступ на любой странице отныне.

Примечание. Это не будет работать при приватном просмотре в Safari, поскольку session_id сбрасывается каждый раз при перезагрузке страницы. (Глупое сафари)

Манприт Сетхи
источник
-9

Вы можете решить эту проблему, добавив заголовок в качестве политики p3p. У меня была такая же проблема на сафари, поэтому после добавления заголовка поверх файлов моя проблема была решена.

<?php
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
?>
Мадан
источник
Вы уверены, что это (все еще) работает с последней версией Safari? Заголовки P3P для IE используются уже много лет, но Safari все еще не работает.
mscha 06
2
Попробуйте очистить все файлы cookie и повторите попытку. Проблема не проявляется, если в вашем браузере уже есть файлы cookie для вашего сайта с iframe.
rmarscher
Хммм, я тоже не могу заставить работать P3P заголовки. Хотя они все еще работают в IE!
Сет Браун
2
Раньше это работало. Но в самой последней версии Safari этого не происходит. Очистите кеш и попробуйте снова ....
chantheman
2
Хочу заявить, что это решение работает. убедитесь, что вы УДАЛИЛИ ВСЕ файлы cookie на сафари. А потом попробуйте это.
dnuske