O Safari não permite que você defina cookies em iframes de domínios diferentes do domínio pai, cabeçalhos CORS do servidor.
Para esclarecer: o usuário está em domainA.com. Um iframe para domainB.com está aberto e tenta autenticar o usuário em domainB.com dentro do iframe. O cabeçalho Set-Cookie é retornado do servidor dentro do iframe domainB.com, com todos os cabeçalhos necessários, mas o Safari não o envia de volta nas chamadas subseqüentes.
Uma solução alternativa antiga estava enviando um formulário a partir do iframe e configurava o cookie na resposta. Acho que eles gostaram do fato de o usuário estar clicando em algo para enviar o formulário. Você precisaria pesquisar o cookie para ver quando a resposta retornaria, pois os envios de formulários não têm retorno de chamada e, no caso dos cookies HttpOnly, você não podia, mas, ei, funcionou! Até que não.
Em seguida, uma solução alternativa mais recente foi redirecionar o usuário para o domínio iframe em uma nova janela / guia, definindo um cookie aleatório e, a partir desse momento, esse subdomínio foi "confiável" dentro do iframe. Novamente, foi necessário um clique para abrir a nova janela / guia, e havia até uma indicação visual da nova abertura da guia. Muita segurança, esses padrões.
E agora, a partir do Safari 13 - Não há mais solução alternativa. Nenhuma configuração de cookie iframe mais segura 🤬
Qualquer outro esquema de autenticação não é bom para nós (por exemplo, cabeçalho Auth-X). Precisamos usar um cookie seguro HttpOnly, pois não queremos que o token seja acessível de maneira alguma pelo javascript do lado do cliente.
Para ser claro, tudo funciona muito bem em qualquer outro navegador.
Alguém tem alguma sugestão?
Editar:
Obrigado pelo link @tomschmidt, que parece a direção certa. Tentei usar a API de acesso à armazenamento da Apple, mas infelizmente solicitei acesso antes de inicializar minha lógica de login com a API:
requestStorageAccess = async() => {
return new Promise(resolve => {
//@ts-ignore
document.requestStorageAccess().then(
function () {
console.log('Storage access was granted');
resolve(true);
},
function () {
console.log('Storage access was denied');
resolve(false);
}
);
});
}
const storageAccessGranted = await requestStorageAccess();
console.log(storageAccessGranted) // prints 'true'
await login();
Ainda assim, os cookies recebidos na resposta da API / login não estão sendo enviados nas chamadas subseqüentes à API :(
fonte
Respostas:
Acho que encontrei a solução: API de acesso a armazenamento da Apple: https://webkit.org/blog/8124/introducing-storage-access-api/
fonte
Portanto, a solução alternativa ainda funciona, desde que a nova janela esteja armazenando o cookie que você deseja armazenar. O iframe ainda não pode armazenar seus próprios cookies. No meu caso, tudo que eu precisava era do cookie de identificação da sessão. Portanto, abro uma pequena janela pop-up quando o usuário concede acesso ao armazenamento. Ele obtém e armazena o cookie de identificação da sessão, fecha e recarrega o iframe. O iframe então tem acesso ao cookie de identificação da sessão e o envia em solicitações subsequentes. Eu acho que isso é apenas temporário, parece que eles removerão o acesso ao armazenamento das janelas pop-up em algum momento no futuro. Talvez eles consertem o iframe não podendo armazenar cookies até então.
fonte