FIX: Bypass service worker on the SSO path (#15558)

This is a workaround a behavior change in Chromium v97.
The following text was sent to the blink-dev mailing list:

> This change broke a SingleSignOn login on the FOSS software Discourse. We have a flow like:
>
> 1. User visits forum.siteA.com, click login
> 2. Gets redirected to idp.siteB.com
> 3. Fills login details
> 4. Gets redirected to forum.siteA.com/session/sso_login?parameters
> 5. Gets redirected to forum.siteA.com/homepage
>
> On step 4, the response includes a `set-cookie` header, with proper `HttpOnly; SameSite=Lax; Secure `and set. But if there is an active service worker, the login will fail as that cookie will be rejected by Chromium due to SameSite rules now.
>
> t=2971 [st=258]        COOKIE_INCLUSION_STATUS
>                        --> domain = "forum.siteA.com"
>                        --> name = "_t"
>                        --> operation = "store"
>                        --> path = "/"
>                        --> status = "EXCLUDE_SAMESITE_LAX, DO_NOT_WARN"
>
> The service worker is a vanilla WorkboxJS service worker that intercepts all GETs with the "Network First" strategy.
>
> Disabling the service worker or using Firefox results in a successful login. There is no warning in either DevTools network tab nor the console that the cookie was rejected.
>
> Chrome 96: login works
> Chrome 97: login does not work
> Chrome 98: login does not work
>
> Is this expected behavior? Even if the request `GET forum.siteA.com` was initiated because of a redirect from a different domain, is it expected that Chrome will silently drop same site cookies from forum.siteA.com?
This commit is contained in:
Rafael dos Santos Silva 2022-01-12 20:01:53 -03:00 committed by GitHub
parent da6f837572
commit 2278c7f82d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 2 additions and 2 deletions

View File

@ -7,7 +7,7 @@ workbox.setConfig({
debug: false
});
var authUrl = "<%= Discourse.base_path %>/auth/";
var authUrls = ["auth", "session/sso_login"].map(path => `<%= Discourse.base_path %>/${path}`);
var cacheVersion = "1";
var discourseCacheName = "discourse-" + cacheVersion;
@ -17,7 +17,7 @@ var externalCacheName = "external-" + cacheVersion;
workbox.routing.registerRoute(
function(args) {
return args.url.origin === location.origin && !args.url.pathname.startsWith(authUrl);
return args.url.origin === location.origin && !authUrls.some(u => args.url.pathname.startsWith(u));
}, // Match all except auth routes
new workbox.strategies.NetworkFirst({ // This will only use the cache when a network request fails
cacheName: discourseCacheName,