I have an iframe on my page. As Safari blocks 3rd party cookies, I am trying to use the Storage Access API as suggested here under 'Developer Guidance': https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/. I have copied the following code from the documentation:
<script type="text/javascript">
window.addEventListener('load', () => {
document.getElementById('test-button').addEventListener('click', () => {
document.hasStorageAccess().then(hasAccess => {
console.log('hasAccess: ' + hasAccess);
if (!hasAccess) {
return document.requestStorageAccess();
}
}).then(_ => {
console.log('Now we have first-party storage access!');
document.cookie = "foo=bar";
console.log(`document.cookie: ${document.cookie}`);
}).catch(_ => {
console.log('error');
});
});
});
</script>
<button id="test-button">Test</button>
Browser console output:
[Log] hasAccess: true
[Log] Now we have first-party storage access!
[Log] document.cookie:
As you can see, the grant seems to be successful but still cannot set the cookie. Does anyone have an idea what's wrong?
Safari Version 13.0.1
EDIT: Console output on Safari 13.1:
[Log] hasAccess: false
[Log] error
Note: The enclosing page is a simple iframe
tag with a src
pointing to this page.
Make sure a cookie has already been set for the domain in a first-party context.
There's a couple of things to look out for with that code sample. Please note the following was tested on Safari 13.1.
document.requestStorageAccess
has to be called as a result of a user action. Despite as documented on the MDN docs, document.hasStorageAccess
does not seem to propagate the user action.A cookie must have already been set on the domain in a first party context. This cookie can either be set by the server as a response header, or by JS using document.cookie. With a bit of further testing, it seems this cookie MUST NOT be set with the domain flag in order for a subsequent cookie to be set in the third party context. This means that in effect, the existing cookie must also be set on the same exact sub domain.