ofetch icon indicating copy to clipboard operation
ofetch copied to clipboard

Set cookies

Open MickL opened this issue 1 year ago • 11 comments

Describe the feature

I have a login route that returns a session cookie but when sending subsequents requests the cookie is not set:

const loginResponse = await ofetch.raw('/login', {
      method: 'POST',
      body: {
        email: '[email protected]',
        password: 'test123',
      },
    });
expect(loginResponse.status).toBe(204);

const securedRouteResponse = await ofetch.raw('/admin/products');
expect(securedRouteResponse).toBe(200); // -> 403

Unfortunately the cookie is never set. I tried to set option credentials: 'include' on both requests with no success. Am I missing something?

Additional information

  • [ ] Would you be willing to help implement this feature?

MickL avatar Apr 08 '24 12:04 MickL

Checking the Set-Cookie attributes, such as Path, Domain, Expires, etc, in the server response headers of the /login endpoint to ensure the cookie is stored correctly

87xie avatar Apr 09 '24 16:04 87xie

Yes it works fine in browser and in Postman

MickL avatar Apr 09 '24 20:04 MickL

I also have the same problem, the application runs fine locally but when deployed to Firebase it cannot get cookies 😥

duy-dev avatar Apr 23 '24 09:04 duy-dev

Try with

const loginResponse = await ofetch.raw('/login', {
      method: 'POST',
      body: {
        email: '[email protected]',
        password: 'test123',
      },
      credentials: "include",
});

sonicjhon1 avatar Apr 26 '24 08:04 sonicjhon1

You mean credentials: include? Thats what I tried as I wrote in the initial issue

MickL avatar Apr 26 '24 08:04 MickL

You mean credentials: include? Thats what I tried as I wrote in the initial issue

Yeah my bad, did you try it with access-control-allow-credentials header set to true in the server?

sonicjhon1 avatar Apr 26 '24 08:04 sonicjhon1

It works in the browser and with Postman, just not in the test or an empty node script with ofetch.

MickL avatar Apr 26 '24 09:04 MickL

Facing the same issue, runs fine locally but not in production. Did anyone figure this out? :(

pratik149 avatar Jun 05 '24 05:06 pratik149

fetch by design is not managing the cookies for you


What you are trying to accomplish is creating a stateful client, which shares state between subsequent requests. fetch, and by extension ofetch, is not designed to do this. Each request is independent. To accomplish your goal, a separate concept of "cookie jar" is required - a storage instance which is going to read response headers, persist cookies and set them on future requests. You can write it yourself or try open source pacakges.

I imagine using fetch-cookie package with ofetch should look like this:

import { $fetch } from 'ofetch'
import makeFetchCookie from 'fetch-cookie'

const fetchWithCookies = makeFetchCookie($fetch.native)
const client = $fetch.create({ fetch: fetchWithCookies })

Aareksio avatar Jun 17 '24 14:06 Aareksio

Thanks for the info!

Can we treat this issue as a feature request then? So ofetch will behave as a cookie jar, automatically setting cookies @pi0 ?

MickL avatar Jun 17 '24 15:06 MickL

I also have the same problem, the application runs fine locally but when deployed to Firebase it cannot get cookies 😥

After many days of researching, I also found the problem. Firebase only accepts one cookie named __session. Hope this information is useful to everyone. Details on this can be found here: https://firebase.google.com/docs/hosting/manage-cache?hl=en#using_cookies

duy-dev avatar Jun 19 '24 08:06 duy-dev

@Aareksio is well explained, ofetch is stateless by design.

However, i see good use cases for stateful cookie (most importantly for testing), therefore made new proposal (~> #435). With stateful instance, we can also register a hook that implements cookie support.

pi0 avatar Aug 28 '24 10:08 pi0