Skip to content

[Feature request] Add a CookieStore option to Request & Response #1384

Open
@jimmywarting

Description

@jimmywarting

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 cookies 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    addition/proposalNew features or enhancementsneeds implementer interestMoving the issue forward requires implementers to express interest

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions