Safari completamente no le permite configurar cookies en iframes de dominios diferentes al dominio principal, maldita sea las cabeceras CORS del lado del servidor.
Para aclarar: el usuario está en domainA.com. Un iframe para domainB.com está abierto e intenta autenticar al usuario en domainB.com dentro del iframe. El encabezado Set-Cookie se devuelve desde el servidor dentro del iframe de domainB.com, con todos los encabezados necesarios, pero Safari no lo devuelve en llamadas posteriores.
Una solución alternativa anterior era enviar un formulario desde el iframe y establecer la cookie en la respuesta. Supongo que les gustó el hecho de que el usuario estaba haciendo clic en algo para enviar el formulario. Tendría que sondear la cookie para ver cuándo regresó la respuesta, ya que los envíos de formularios no tienen devoluciones de llamada, y en el caso de las cookies HttpOnly no puede, pero ¡hey, funcionó! Hasta que no lo hizo.
Luego, una solución más reciente fue redirigir al usuario al dominio del iframe en una nueva ventana / pestaña, estableciendo una cookie aleatoria allí, y desde ese momento, ese subdominio fue "confiable" dentro del iframe. Nuevamente, se requirió un clic para abrir la nueva ventana / pestaña, e incluso hubo una indicación visual de la apertura de la nueva pestaña. Mucha seguridad, tales estándares.
Y ahora, a partir de Safari 13: no más soluciones alternativas. No más configuración segura de cookies de iframe 🤬
Cualquier otro esquema de autenticación no es bueno para nosotros (por ejemplo, encabezado Auth-X). Necesitamos usar una cookie segura HttpOnly, ya que no queremos que el token sea accesible de ninguna manera por parte del cliente javascript.
Para ser claros, todo funciona muy bien en cualquier otro navegador.
¿Alguien tiene alguna sugerencia?
Editar:
Gracias por el enlace @tomschmidt, esa parece ser la dirección correcta. Intenté usar la API de acceso de almacenamiento de Apple, pero desafortunadamente, aunque me estoy asegurando de solicitar acceso antes de inicializar mi lógica de inicio de sesión con la 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();
Aún así, las cookies recibidas en la respuesta de API / login no se envían en llamadas posteriores a la API :(
fuente
Respuestas:
Creo que podría haber encontrado la solución: la API de acceso de almacenamiento de Apple: https://webkit.org/blog/8124/introducing-storage-access-api/
fuente
Por lo tanto, la solución aún funciona, siempre y cuando la nueva ventana almacene la cookie que desea almacenar. El iframe aún no puede almacenar sus propias cookies. En mi caso, todo lo que necesitaba era la cookie de identificación de sesión. Entonces, abro una pequeña ventana emergente cuando el usuario concede acceso al almacenamiento. Obtiene y almacena la cookie de ID de sesión, cierra y vuelve a cargar el iframe. El iframe luego tiene acceso a la cookie de identificación de sesión y la envía en solicitudes posteriores. Sin embargo, creo que esto es solo temporal, parece que van a eliminar el acceso al almacenamiento de las ventanas emergentes en algún momento en el futuro. Tal vez arreglen el iframe para que no puedan almacenar cookies para entonces.
fuente