FGF-College-Work / Forum

:beer: Espaço dedicado a discussões e tira dúvida sobre disciplinas e conteúdo tecnológico.
MIT License
13 stars 4 forks source link

Safari iframe cookie workaround #159

Open marcialwushu opened 5 years ago

marcialwushu commented 5 years ago

Safari iframe cookie workaround

O Safari, por padrão, descarta os cookies definidos em um iframe, a menos que o host que está atendendo ao iframe tenha definido um cookie antes, fora do iframe. O Safari é o único navegador que faz isso.

The 10k foot view

Para contornar o problema, o site pai (src) e filho / iframed / remoto (dest) precisam trabalhar juntos, se o site de origem quiser que os usuários acessem o destino por meio do iframe e não possam presumir que o usuário visitou o host de destino antes.

Normalmente, um usuário navega da página A, sem iframe externo, para a página B, com um iframe externo, clicando em um link direto entre os dois. Para fazer a solução funcionar, o link da página A é, em vez disso, um URL de "rejeição" no site de destino, que define um cookie (sem requisitos de nome, valor etc.) e redireciona de volta à página B. O redirecionamento pode ser difícil -codificado para segurança ou deixado mais aberto.

O aviso

Os arquivos a seguir são um exemplo ingênuo do problema / solução. Você vai querer pensar em sua solução com mais cuidado ... não copie e cole esses trechos em um ambiente de produção! Eu não pensei nas ramificações de segurança do que é mostrado aqui ... o que significa que existem algumas, e elas não são boas. Voce foi avisado.


GIST

marcialwushu commented 5 years ago

I just put something in an iframe and was pulling my hair out that some users were reporting issues...turned out to be this. Thank you very much for taking the time to do this write up. Also very thankful for the "safari-cookie-in-iframe" reference....here is what I went with based on that:

PARENT

var is_safari = navigator.userAgent.indexOf("Safari") > -1;
// Chrome has Safari in the user agent so we need to filter (https://stackoverflow.com/a/7768006/1502448)
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
if ((is_chrome) && (is_safari)) {is_safari = false;}  
if (is_safari) {
    // See if cookie exists (https://stackoverflow.com/a/25617724/1502448)
    if (!document.cookie.match(/^(.*;)?\s*fixed\s*=\s*[^;]+(.*)?$/)) {
        // Set cookie to maximum (https://stackoverflow.com/a/33106316/1502448)
        document.cookie = 'fixed=fixed; expires=Tue, 19 Jan 2038 03:14:07 UTC; path=/';
        window.location.replace("http://vit-demos.appspot.com/_safari_fix.html");
    }
}

CHILD

document.cookie = 'safari_cookie_fix=true; path=/';
window.location.replace(document.referrer);
marcialwushu commented 5 years ago

I can't make this work with the solution : https://github.com/vitr/safari-cookie-in-iframe , i create have an site B in a Iframe in A, so in A i write this code :

var is_safari = navigator.userAgent.indexOf("Safari") > -1;
// Chrome has Safari in the user agent so we need to filter (https://stackoverflow.com/a/7768006/1502448)
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
if ((is_chrome) && (is_safari)) {is_safari = false;}  
if (is_safari) {
    // See if cookie exists (https://stackoverflow.com/a/25617724/1502448)
    if (!document.cookie.match(/^(.*;)?\s*fixed\s*=\s*[^;]+(.*)?$/)) {
        // Set cookie to maximum (https://stackoverflow.com/a/33106316/1502448)
        document.cookie = 'fixed=fixed; expires=Tue, 19 Jan 2038 03:14:07 UTC; path=/';
        window.location.replace("http://vit-demos.appspot.com/_safari_fix.html");
    }
}

and create a file called _safari_fix.html with this code :

document.cookie = 'safari_cookie_fix=true; path=/';
window.location.replace(document.referrer);

but the workaround doesn't work

marcialwushu commented 5 years ago

_safari_fix.html

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
<script>
  document.cookie = 'safari_cookie_fix=fixed; path=/';
  if (window.location.href.indexOf('verbose') > -1) { // you should remove or comment this line
    alert('safari fix has been applied'); // you should remove or comment this line
    setTimeout(window.location.replace(document.referrer), 2000); // you should remove or comment this line
  } else { // you should remove or comment this line
      window.location.replace(document.referrer) //>>>>>>> leave this line ONLY <<<<<<<<
  } // you should remove or comment this line
</script>
</body>
</html>
marcialwushu commented 5 years ago

.htaccess mobile cookie set

Sure you can -- use [CO] flag to set the cookie. For example:

RewriteRule ^(.*)$ http://m.stage.sunjournal.com/$1 [L,R=302,CO=mobile:yes:m.stage.sunjournal.com:0:/]

HTACESS COOKIE

marcialwushu commented 5 years ago

session_set_cookie_params

(PHP 4, PHP 5, PHP 7)

session_set_cookie_params - Define os parâmetros do cookie de sessão

Descrição

session_set_cookie_params ( int $lifetime [, string $path [, string $domain [, bool $secure=FALSE [, bool $httponly=FALSE ]]]]): bool
session_set_cookie_params ( array $options ): bool

Defina os parâmetros do cookie definidos no arquivo php.ini . O efeito dessa função dura apenas a duração do script. Assim, você precisa chamar session_set_cookie_params () para cada solicitação e antes que session_start () seja chamado.

Esta função atualiza os valores ini de tempo de execução das chaves de configuração do PHP correspondentes que podem ser recuperadas com o ini_get () .


PHP.NET

marcialwushu commented 5 years ago

As PHP's Session Control does not handle session lifetimes correctly when using session_set_cookie_params(), we need to do something in order to change the session expiry time every time the user visits our site. So, here's the problem.

<?php
  $lifetime=600;
  session_set_cookie_params($lifetime);
  session_start();
?>

This code doesn't change the lifetime of the session when the user gets back at our site or refreshes the page. The session WILL expire after $lifetime seconds, no matter how many times the user requests the page. So we just overwrite the session cookie as follows:

<?php
  $lifetime=600;
  session_start();
  setcookie(session_name(),session_id(),time()+$lifetime);
?>

And now we have the same session cookie with the lifetime set to the proper value.