Everyone’s already moved onto using service workers to implement third party cookies. I know because we are using it in production.
-edit-
This is how we use it:
We have two domains.
Our main site `widget.com` and `widgetusercontent.com`.
`widget.com` contains an iframe from `widgetusercontent.com`.
We have a service that runs on `widgetusercontent.com/service` that is controlled by us, but it needs to be authenticated with a temporary credential (doesn't matter if it gets leaked) and cannot run on the same domain as `widget.com` since it also contains user generated content.
We used to embed the URL `widgetusercontent.com/service?auth=$AUTH_COOKIE` on `widget.com` and have the `widgetusercontent.com/service` set the cookie, but this no longer works because this is third party cookie and has never worked on Safari.
The solution is to load `widgetusercontent.com/service` as a blank page containing only a service worker. We ask this page to load `widgetusercontent.com/service/sw.js?auth=$AUTH_COOKIE`. The service we control returns a service worker with the auth cookie embedded in it, and is set to rewrite every request under `widgetusercontent.com/service/*` and inject the $AUTH_COOKIE into the request header.
I came up with this myself but I assume others would have as well.
I don't know if this'll work for tracking and other nefarious stuff ad networks use but this is a legitimate use case for us.
Yes it works in Safari. Cookies don’t work but this does.
Interesting, thanks for the update. In my understanding most browsers now partition their cache for third-party resources like iframes, making it dependent on the combination of the embedding and embedded domains (as otherwise it would provide a trivial way to set third-party "cookies" e.g. via ETags). So if you'd load the service worker from "widgetusercontent.com" on another site, the browser would not use the cached version it has from "widget.com", so you wouldn't be able to pass the same auth cookie to your service (I haven't tested that though).
That said for your use case I think you could set a first-party cookie on "widget.com" and pass that to the iframe. That would require a script on the page though as opposed to an iframe, so maybe your service worker version is easier to implement.
> and cannot run on the same domain as `widget.com` since it also contains user generated content.
Why not host at usercontent.widget.com? You can pass credentials via a frame postMessage, are protected by same-origin policy, and cookies would be considered first-party
Incognito mode blocks third party cookies by default and apparently there is a bug in Safari up to iOS 12 that treats None as strict:
>Versions of Safari and embedded browsers on MacOS 10.14 and all browsers on iOS 12. These versions will erroneously treat cookies marked with `SameSite=None` as if they were marked `SameSite=Strict`. This bug has been fixed on newer versions of iOS and MacOS.
that's the root of it right? Many app servers or "wafs" inject/validate csrf tokens on requests/responses. There may be a way to set the SameSite flag on cookies at the server level without even having to touch app code. "if SameSite isn't set then set it to None".
I've been running into this issue in an number of projects all involving SSO and custom in-house IDP implementations. It's an easy fix but getting the teams together and coordinated has been the hardest part.
Service workers are a lot "stickier" than that. If you think about it, they are all about caching. A service worker activation could count as a cookie itself since it can modify future requests, and if you modify the requests in a way that it emulates a cookie being set then it is a cookie.
-edit-
This is how we use it:
We have two domains.
Our main site `widget.com` and `widgetusercontent.com`.
`widget.com` contains an iframe from `widgetusercontent.com`.
We have a service that runs on `widgetusercontent.com/service` that is controlled by us, but it needs to be authenticated with a temporary credential (doesn't matter if it gets leaked) and cannot run on the same domain as `widget.com` since it also contains user generated content.
We used to embed the URL `widgetusercontent.com/service?auth=$AUTH_COOKIE` on `widget.com` and have the `widgetusercontent.com/service` set the cookie, but this no longer works because this is third party cookie and has never worked on Safari.
The solution is to load `widgetusercontent.com/service` as a blank page containing only a service worker. We ask this page to load `widgetusercontent.com/service/sw.js?auth=$AUTH_COOKIE`. The service we control returns a service worker with the auth cookie embedded in it, and is set to rewrite every request under `widgetusercontent.com/service/*` and inject the $AUTH_COOKIE into the request header.
I came up with this myself but I assume others would have as well.
I don't know if this'll work for tracking and other nefarious stuff ad networks use but this is a legitimate use case for us.
Yes it works in Safari. Cookies don’t work but this does.