-
Notifications
You must be signed in to change notification settings - Fork 311
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
Add cookie accessor/setter methods? #707
Comments
Would this we SW only or also go into other global scopes? |
I think this is an opportunity to introduce a decent cookie API. Async, so it can be accessed from worker contexts. I imagine this would be part of the fetch spec, @annevk?
Usage: // read cookies value
navigator.cookies.get('hello').then(c => c && c.value).then(value => {
if (value) {
// …
}
});
// create/overwrite cookie value
navigator.cookies.set('hello', 'world', {
path: '/foo/'
});
// change cookie value
navigator.cookies.get('viewCount').then(viewCookie => {
var viewCount = (viewCookie ? Number(viewCookie.value) : 0) + 1;
var date = new Date();
date.setFullYear(d.getFullYear() + 20);
return navigator.cookies.set('viewCount', viewCount, {
expires: date
});
});
// delete cookie
navigator.cookies.delete('viewCount').then(cookieWasDeleted => {
// …
});
// output all cookie name/vals as urlencoded string
navigator.cookies.getAll().then(cookies => {
var params = new URLSearchParams();
for (var cookie of cookies) {
params.append(cookie.name, cookie.value);
}
return params.toString();
}); |
I guess Cookie.set('hello', 'world') |
Looks awesome! Just couple of questions:
|
I prefer I'm not a great fan of first-letter-capital object names, it makes me feel I can |
Is there any benefit in: navigator.cookies.get('hello').then(cookie => {
cookie.value += ' foobar';
return navigator.cookies.set(cookie);
}); …if not, all cookie properties should be
Copy/paste error, sorry!
Interesting. If we're going to remove |
If we come up with a better API, it should be accessible from
You can in the design above. |
@pornel points out (on Twitter) that maybe "secure" should default to |
Do you mean that we can't make values writable because setting them should be asynchronous? If so, then yes, all of them are readonly.
I like the idea, although removing The only downside of this is that if someone really needs to get all the cookies, he needs to use more complex and slower construction like function cookieEntries() {
return navigator.cookies.keys().then(
keys => Promise.all(keys.map(
key => navigator.cookies.get(key).then(value => [key, value])
))
);
} So I'd propose to add both |
Perhaps |
I wonder if we should wait until same-origin cookies are more established before exposing a new API. Exposing anything but same-origin cookies would be another sidechannel of sorts. Also, I suspect we would restrict a new API, especially for cookies, to secure contexts these days. So only generating secure cookies makes sense. |
@jakearchibald For educational purposes, why throw when both are set? AFAIK, it's not uncommon for devs to set both, or receive cookies that have only Nonetheless, the older browsers that accept only |
Because it's ambiguous which one to use for determining deadline. |
I don't think we should even expose |
@RReverser @annevk Ahh, that makes sense. I agree, |
Cookie names are not unique. Only the combination of name, domain-or-implicit-pseudo-origin, and path is unique, and even that combination is unique only at a single point in time and only with a consistent cookie store. Also, shouldn't set also be asynchronous, and perhaps even result in promise rejection if a later-initiated update collided with it before it completed? In any case, shouldn't it work asynchronously and only finish once the change is synchronized across the session? |
I think we should shoot for something async-map-like, which #707 (comment) diverges from. Agreed it should be secure-only. Probably should be same-origin cookies only as well. Using dates in APIs is always tricky, especially since they are mutable. (Not just a question of "can you set Unsure why USVString. What are the restrictions on cookie names anyway? Fuller proposal to follow. |
Also, perhaps self.cookies.match and self.cookies.matchAll might make more sense since it's an asynchronous operation rather than a simple getter. I think the name should be optional in each case. self.cookies.match().then(function(cookie){
/* gets the first cookie, if any are visible to scripts on this origin
(one of the narrowest-scoped ones) */ })
self.cookies.matchAll().then(function(cookies) {
/* gets all cookies visible to scripts on this origin, ordered from
narrowest-scoped to broadest-scoped */ })
self.cookies.match('SAPISID').then(function(cookie){
/* gets the narrowest-scoped cookie named 'SAPISID' visible
to scripts on this origin, if at least one exists */ })
self.cookies.matchAll('SAPISID').then(function(cookies){
/* gets all cookies named 'SAPISID' visible to scripts on this
origin, ordered from narrowest-scoped to broadest-scoped */ } This lookup interface provides the same capabilities as document.cookie. If more capabilities are declared fit for web consumption they might be implemented by adding a second optional parameter with matching options. Would you expose parameters on read cookies? The document.cookie interface does not, and simply concatenates all the in-scope cookies in a fairly well-defined but not standardized order. |
"Same-origin cookies only" explicitly won't work for SAPISID and other domain-wide synchronization cookies. Also, being able to subscribe to script-visible cookie jar changes would be super-awesome and would vastly reduce wakeups and power usage for apps synchronizing with sign-in state. Right now many web apps do this by periodic polling, typically being forced into a bad compromise between laggy session synchronization and shortened battery life. Something like this might work well: https://developer.chrome.com/extensions/cookies#event-onChanged (This has been used successfully for power-efficient session synchronization in extensions.) |
It does occur to me that restricting to same-origin cookies might prevent @cramforce's original use case :-/. Also as @bsittler reminds us it sounds like the key is not id, but instead id + path + other stuff. With that in mind I have two proposals. One is based on a simplified model: path is always "/", secure is always true, httponly is always false, and same-origin means no domain. So the keys can just be strings. The other is more full-featured, adding path and domain and dropping the same-origin restriction (but keeping secure-only). Simplified
This looks kind of like async local storage with expiration built-in, heh. Full-FeaturedThis version could potentially be the same just with domain and path: partial dictionary CookieOptions {
USVString domain; // defaults to location.origin (*not* host)
USVString path = "/";
}
partial interface Cookie {
readonly attribute USVString domain;
readonly attribute USVString path;
} However I am unsure how well the string-keyed get/set/has/delete can work given that the key is actually something like
Alternately we can just say that cookies are stupid and putting lipstick on that pig is not a good idea. |
Given that we so far did not introduce them in workers I think that might be okay. Just use cookies as synchronization token, and that's it... |
In a Worker I can write a 10 minute polyfill for all APIs described in this As of now cookies are the only mechanism that allow for cross sub domain E.g. you lock into foo.slack.com as user X. At the end of the session you Comparing a cookie value stored in IndexedDB to the actual cookie value is On Tue, Jun 9, 2015 at 10:12 PM Anne van Kesteren [email protected]
|
That should be considerably easier once you can use service workers as a service (through |
That isn't going to change that spinning up 3, 5, 20 or even 100 SWs on Maybe we could make the API read-only initially to reduce complexity.
|
With navigator.connect one would need to implement a flow like:
Please lets not require hacks like this as the first thing privacy On Wed, Jun 10, 2015 at 6:55 AM Malte Ubl [email protected] wrote:
|
How is a cookie API going to change that? I have the feeling the scenario here is not complete. |
If you have access to cookies (read cross sub domain information) workers On Wed, Jun 10, 2015 at 7:07 AM Anne van Kesteren [email protected]
|
A few points:
|
Given that, async map with full access to exactly the same data as
|
[Apologies for the typos, I pressed send too soon.] |
FYI, as noted in issue #837, the ability to read cookies is fundamental to extending signed in sessions on a number of major websites. I'd encourage this group to prioritize this feature. |
I like @domenic's full-featured proposal, and agree that
If I wanted to find all the (non-http-only) cookies that would be sent to
This means making "name" a property of the cookie. |
So I fully agree that we probably want some kind of new and improved cookie API that works in service workers, but I don't believe that such an API should be part of the service worker spec, so this repository is probably not the best place to discuss details about the exact shape of the API. Not sure where such an API should live though (as part of HTML? as a separate spec in the web platform WG? As a proposal/spec in the WICG?) Personally I like small specs for well defined features so having a separate spec for this seems like it would make sense. |
@inexorabletash not quite sure how needing to interop with the existing Cookie behavior would imply this being part of HTML? The part of the HTML spec that deal with cookies is pretty much two lines of spec text calling out to the ietf cookie spec to get/set cookies. Referring to the same IETF spec from a cookie API spec seems like all that would be needed to achieve interop (of course a cookie API spec will have to reference parts of HTML and SW to properly specify its API). Aside from that, spinning up a github repo for now and later migrate that to WICG sounds good to me. |
@mkruisselbrink is probably right that there's no dependency. For the record, I was thinking of consistency issues but we've given up on that anyway - see the big warning near https://html.spec.whatwg.org/#dom-document-cookie |
Agreed |
This is also a design sketch for the new API and is loosely based on/inspired by w3c/ServiceWorker#707
Just created a repo: https://github.com/bsittler/async-cookies-api It doesn't have a useful explainer yet but perhaps it would be useful to move further cookie API discussion there, file issues, etc.? |
@inexorabletash I think implementers have not quite given up on consistency issues and we shouldn't either. It's just no longer in the form of the storage mutex. We should be able to work something out though between the HTML Standard and @bsittler's work. |
There's an explainer for the asynchronous cookies API proposal now: https://github.com/bsittler/async-cookies-api/blob/gh-pages/explainer.md (but the polyfill there is out of date and should be ignored for now) I welcome any and all of your comments, feedback, pull requests, recommendations for change in style or venue, and issue reports! |
Also, re: consistency, the proposed API does not introduce any new consistency requirements but does leave open the possibility of eventually introducing a stronger consistency guarantee |
The explainer and polyfill are updated and synchronized and I've started a thread on the WICG discourse forum for the proposal. |
Just thought about one time cookies... Just wondering if something like this would be useful let cookie = new Cookie(...)
fetch(url, {
cookies: [cookie]
}) or: let cookieJar = new CookieJar()
let cookie = new Cookie(...)
cookieJar.put(cookie)
fetch(url, {
cookieJar: cookieJar
}) |
I have just had a use case for adding cookies to a response in a serviceworker before allowing the response to proceed to the browser tab. This doesn't currently work because |
Currently our end-users are sending cookies for static files because our asset origin is a subdomain and we can't specify a list of allowed subdomains in the So I'd like to be able to modify/drop cookies on outgoing requests in service workers. |
@frvge Here you go:
|
Use case for cookies in SW: |
Chrome did an original trial of the cookie store api recently, but I don't think it's still running: https://groups.google.com/a/chromium.org/forum/m/#!msg/blink-dev/pdxkBoURmaA/vOTkwUBCBAAJ If you are interested in that feature you may want to post something there. |
Yep, I think this issue is superseded by https://wicg.github.io/cookie-store/. |
So, still not available? |
@joelpro2
|
Is it possible to modify the cookies from Service Worker based on different URL? It's not useful if can't set cookies per request and only to origin that register Service Worker. I was thinking of creating service worker that block cookies when user don't give consent. I just want to see what is possible. |
In keeping with our approach of only adding APIs as-needed, we've had a request come in from @cramforce for access to cookies from the SW context.
We'll need something asynchronous; e.g.:
I'm afraid it won't lock, so might get out of sync with documents more easily than script access does today, but we should perhaps try it out and see how it goes.
While we're at it: do we want more structured cookie types for both these records and the cookies entries in
Response
objects?The text was updated successfully, but these errors were encountered: