Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support modifying cookies on an intercepted fetch #837

Closed
owencm opened this issue Feb 22, 2016 · 9 comments
Closed

Support modifying cookies on an intercepted fetch #837

owencm opened this issue Feb 22, 2016 · 9 comments

Comments

@owencm
Copy link

owencm commented Feb 22, 2016

There is an important use case around auth and identity where you may want to intercept fetch requests, detect the cookies are out of date, generate new ones (via a fetch to the server) and then send the original request with the new cookies.

Is that possible with SW today? It seems to me that you can't modify the cookie headers (), and it's unclear whether a currently intercepted request will be modified by a setCookie call.

@eliaswald @slightlyoff

@mkruisselbrink
Copy link
Collaborator

I'm not sure what "detect the cookies are out of date" means, but cookies don't become part of a request until after a service worker has potentially processed it (in http fetch step 3 a service worker gets access to the request, and it isn't until step 4.4 when a request eventually reaches step 12.1 of HTTP-network-or-cache fetch that cookies get applied to the request).

So a SW could definitely modify what cookies will be part of a request, if it had an API to do so. Currently service workers don't have any APIs to read/modify cookies (#707) though.

@owencm
Copy link
Author

owencm commented Feb 22, 2016

To expand on the issue: some sites set cookies to expire after short periods for security reasons, but would like to keep a longer term cookie on the client, and then when the short term cookie expires they'd like to make a single "cookie refresh" request with the long term cookie that will provide a new short term cookie which can be added to the original request that had the expired cookies.

If cookies only get added after the SW has processed then would the following possibly work?

  1. Intercept a request to /index.html
  2. Use the new (not yet implemented) getCookies API to inspect the cookies and decide whether they need refreshing
  3. Make a request to the refresh cookies endpoint, which would use headers to set a cookie on the client
  4. Let the request intercepted in 1 go to the network, as at this point the new cookies set in 3 would be added to it

On a high level it sounds like cookies get added after the request leaves the SW so modifying cookies on a request is possible by adding cookies directly to the origin before the request leaves the SW. Let me know if that doesn't sound true though.

@jakearchibald
Copy link
Contributor

@owencm that would work if we had a way to read cookies, but I can't quite get my head around the use-case. If the server knows that cookies need updating, why is there a problem?

Eg:

  1. Request made to server with cookie foo=bar
  2. Server realises that's out of date, and treats it as the correct foo=world
  3. Sends response along with set-cookie foo=world

@owencm
Copy link
Author

owencm commented Feb 26, 2016

@jakearchibald the issue is that for some legacy backends (spoiler: there are lots of these out there) it's near impossible to modify all possible endpoints on the server to check and re-issue a new cookie. A much more practical engineering approach is to check in one place in the SW and then hit a single endpoint to refresh the cookies before letting the original fetch proceed.

I know of some specific companies affected by this but don't want to name names. But some identity folk at Google think that if this approach could be made to work then it would be practical for a number of very large sites to keep users logged much longer.

@owencm
Copy link
Author

owencm commented Mar 4, 2016

@mkruisselbrink I just tried the following in a service worker:

  1. Intercept a fetch request
  2. Make a new request to an endpoint that includes Set-Cookie with a new cookie
  3. Once that request comes back, wait 1 second and then let the original fetch request go to the server

I've noticed that the second request that goes to the server doesn't include the cookie set by the first request. Is that as expected? Any thoughts about other ways to do this today without setCookie?

@mkruisselbrink
Copy link
Collaborator

@owencm From just reading the various specs I would have expected that to work (the original fetch to include the cookies set by the in-between request). So that's either a bug in the chrome implementation, or I'm misunderstanding the fetch spec.

@wanderview
Copy link
Member

@owencm Can you test what Firefox does in that case?

@owencm
Copy link
Author

owencm commented Mar 5, 2016

@mkruisselbrink @wanderview I couldn't try this in Firefox since I couldn't find any documentation about how to debug service workers there and inspect their console (link?)

I did resolve the issue though. It turns out that the Set-Cookie header is ignored on responses unless the fetch that triggered it specified credentials: 'include', which wasn't my understanding of that option.

I've now got this working as expected, this for now it is possible to hack around the existence of setCookie if you are happy to deal with an additional round trip to the server.

@owencm owencm closed this as completed Mar 5, 2016
@jcubic
Copy link

jcubic commented May 16, 2024

@jakearchibald why Service Worker can't create cookies? Header Set-Cookie created from service worker is removed from the response. What is the reason behind this?

I want to create an API in service worker using Wayne library, and I can't do this properly with JWT refresh and access tokens because cookies are not supported in Service Worker.

Example code:

self.addEventListner('fetch', (event) => {
  const url = new URL(event.request.url);
  if (url.pathname === '/api/login') {
    const headers = {
      "Set-Cookie": "TestCookie=foo; path=/; Max-Age=60;"
      "TestHeader": "foo"
    };
    event.respondWith(new Response('Hello!', { headers }));
  }
});

The Set-Cookie header is removed by the browser, the TestHeader is present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants