Description
I was looking into how some form of how a cookie jar could fit into NodeJS and Deno.
...it totally lacks any form of cookie handling. A default cookie jar would not be so perfect for backend either.
There exist some grate libraries like tough-cookie but isn't so web-ish when it comes to something as spec'ed as the CookieStore
I was thinking that it would be cool if you could construct CookieStore with new CookieStore()
and being able to pass this to fetch/Request as an option. and so that we can agree upon a unified way of dealing with cookie jars in both Deno and NodeJS. while sending, reciving and encoding/decoding cookie strings
// this is just a ruff sketch up / proposal
// not sure if it would actually look anything like this in the end
// not even 100% sure if a CookieStore could handle all your scenario
// I don't know how CookieStore could behave with multiple domains, maybe it's doable with
// cookieStore.get({ name, url }) and not cookieStore.get({ name })
// then servers can be free to read httpOnly cookies without any restrictions
const cookieStore = new CookieStore()
const request = new Request(url, { cookieStore })
fetch(url, { cookieStore }).then(response => {
// Any response headers that had 'set-cookie' will now be in this CookieStore (incl. those in redirect)
response.cookieStore === cookieStore // true
})
// unspecified cookieStore in browser would default to the default global cookie store
fetch(url).then(response => {
response.cookieStore === window.cookieStore // default cookieStore
})
// Deno and NodejS could technically create a new CookieStore instance if no cookieStore is provided
const req = new Request(url)
req.cookieStore // new instances of CookieStore
fetch(req).then(response => {
response.cookieStore === cookieStore // false
response.cookieStore instanceof CookieStore // true
// response.headers would not contain any `set-cookie` like the browser
response.headers.has('set-cookie') // will always be false
})
// Service worker could modify a CookieStore
self.onfetch = evt => {
evt.request.cookieStore.get('xyz').then(...)
}
// unrelated to fetch... but:
// http servers could maybe also utilize CookieStore in some way also and behave a bit like service workers?
import express from 'express'
const app = express()
app.use(async (request, response) => {
// logged in user with a cookie 'xyz' makes a request to 'POST /blog'
// So the incoming request contains a newly created cookieStore specific to this user only
if (! (await request.cookieStore.get('xzy'))) {
// the user don't seem to be logged in with the cookie xyz
// response.cookieStore is a (completly new? or the same) CookieStore we could utilize
// for setting new cookies that would be sent back to the response/client
await response.cookieStore.set('xyz', { ... })
}
})
This would take care of setting request cookie
s that exist in the store and parsing set-cookies
like during redirects as well. + it would also simplify getting/setting cookies, and the Header class wouldn't need any special handling like #1346, #973 (we could forbid the set-cookie
header like the browser dose it and also remove any cookie
header from the response.headers as well)
I was maybe thinking this could be useful for the web as well where you have the desire to handle multiple sessions/accounts simultaneously and dealing with cookies yourself in different tabs. This could also be a way of telling a single page application that cookies should never store a cookie on the clients machine (whetter it be session or persistent) maybe you could store a CookieStore
in the IndexedDB
? otherwise it would totally be discarded when you leave the page. This could be useful for banks so that you are logged out as soon as you close/refresh the page, and having to login again.
if you could pass a own instances of CookieStore to the request then it would also mean that any sub-sequent request to eg /static/css/main.css
wouldn't send any cookie either via a <link>
tag