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

Refreshing a page removes the cookie using the local provider #732

Open
jorni-moddit opened this issue Apr 9, 2024 · 53 comments
Open

Refreshing a page removes the cookie using the local provider #732

jorni-moddit opened this issue Apr 9, 2024 · 53 comments
Labels
bug A bug that needs to be resolved help-needed Action needed: The help of the community would be appreciated p3 Minor issue provider-local An issue with the local provider

Comments

@jorni-moddit
Copy link

Environment

Reproduction

We're using a WordPress back-end with the simple-JWT plugin.
For this example I returned a hardcoded body in the api/auth/[...].ts
And there is a simple login form.

https://stackblitz.com/edit/github-gpkaqq?file=server%2Fapi%2Fauth%2F[...].ts

Describe the bug

After logging in a cookie is set, when not configured it's under auth.token and I have an authenticated state.
image

After a page refresh this cookie is removed.
image

Additional context

No response

Logs

No response

@jorni-moddit jorni-moddit added bug A bug that needs to be resolved pending An issue waiting for triage labels Apr 9, 2024
@MisterNox
Copy link
Contributor

MisterNox commented Apr 9, 2024

Unfortunately I cannot reproduce your issue. When I try it with your stackblitz example and refresh the page the cookie persists and I am still authenticated (I tried it with Firefox and Chrome).

However, I had a similar issue when I touched the cookie after it was set by the signIn method with the Cookies class of the js-cookie library. My intention was to build a wrapper around the signIn to dynamically set the expires attribute of the cookie by the value the jwt token comes with instead of relying only on the static definition via the config in nuxt. Don't know if this is related to the useCookie method or the Set-Cookie header. By the way I use simple-jwt as well.

Do you touch the cookie somewhere in your process flow? What helps me in this situations when it seems to get buggy is hard refreshing via Ctrl + Shift + R and/or closing the browser entirely and/or deleting the .nuxt folder and let it rebuild everything from scratch. Dont know if it helps in your situation but you could give it a try.

@husseinjahan
Copy link

husseinjahan commented Apr 16, 2024

I have the same Issue.

I'm using local authentication but connect to api to get user login. Sometimes not all the times when I refresh the browser, the response comes with a 'SET-COOKIE' response header that clears auth token (I don't know why!). I think there is a bug.

Is there any workaround about it?

I checked this in development and production server with chrome and firefox browsers.

image

@FireMasterK
Copy link

FireMasterK commented Apr 17, 2024

This only happens in the production build, I can reproduce the issue on the stackblitz too with npm install && npm run build && npm run preview.

Edit: removing the set-cookie headers from the nuxt server doesn't fix it, the client is unauthenticated despite having a valid cookie.

@Norel
Copy link

Norel commented Apr 18, 2024

I have the exact same problem except I can't reproduce the bug in a local project (dev or prod), only when deployed to a distant server.

@FireMasterK
Copy link

I have the exact same problem except I can't reproduce the bug in a local project (dev or prod), only when deployed to a distant server.

Same case for me, except I'm able to reproduce it on the Stackblitz in production mode!

@phoenix-ru
Copy link
Collaborator

phoenix-ru commented Apr 25, 2024

I can reproduce on playground-local using pnpm build && pnpm nuxi preview.

Adding this to the reproduction app.vue fixes the issue.

onMounted(() => {
  getSession({ force: true });
});

Why is it needed, however? And why doesn't it work without force: true?

I assume it is related to

if (!token && !getSessionOptions?.force) {
loading.value = false
return
}
and
onMounted(() => {
// When the page is cached on a server, set the token on the client
if (_rawTokenCookie.value && !rawToken.value) {
setToken(_rawTokenCookie.value)
}
})

If someone could further investigate and propose a fix, it would be great!

@phoenix-ru phoenix-ru added p3 Minor issue help-needed Action needed: The help of the community would be appreciated provider-local An issue with the local provider and removed pending An issue waiting for triage labels Apr 25, 2024
@Norel
Copy link

Norel commented Apr 26, 2024

It turns out that using node 18 is problematic when using nuxt fetch (nuxt/nuxt#12552).
Upgrading to node 20 fixed the issue for me.
Stackblitz is probably using node 18 too.

@FireMasterK
Copy link

It turns out that using node 18 is problematic when using nuxt fetch (nuxt/nuxt#12552). Upgrading to node 20 fixed the issue for me. Stackblitz is probably using node 18 too.

I'm able to reproduce it on node 20 still, my Dockerfile uses the node:20-slim image.

@ndro
Copy link

ndro commented Apr 29, 2024

I have the same issue with local provider.

Cookie got removed in Firefox after reloading the browser or updating the app. But it's fine in Chrome.

my auth config in nuxt.config.ts:

  auth: {
    baseURL: `${process.env.SOME_DOMAIN_API}`,
    provider: {
      type: 'local',
      pages: {
        login: '/login'
      },
      endpoints: {
        signIn: { path: '/login', method: 'post' },
        signOut: { path: '/logout', method: 'delete' },
        signUp: { path: '/register', method: 'post' },
        getSession: { path: '/me', method: 'get' }
      },
      token: {
        signInResponseTokenPointer: '/token',
        type: '',
        maxAgeInSeconds: 1209600
      },
      sessionDataType: {
        data: {
          // some custom data
        }
      },
    },
    globalAppMiddleware: {
      isEnabled: true
    }
  },

@albank
Copy link

albank commented Apr 29, 2024

My cookies are also set to empty 4 times like @husseinjahan above, when I refresh the page. I have the issue with both node18 and node20.
However, when using the network address created by nuxt, I don't have the issue:
Ex.
Network: http://172.19.x.x:3000/

When I use my development mydomain.localhost that points to that address, my cookies get deleted 4x.

Any idea why ?

@mbellamyy
Copy link

mbellamyy commented May 21, 2024

I can reproduce OP's scenario when I use Stackblitz's embedded browser (on the right column), but I cannot reproduce it when I open the output in a new tab

Edit: I can reproduce it either way now :) Really frustrating

I have the same issue with the refresh provider.

@mbellamyy
Copy link

can reproduce on playground-local using pnpm build && pnpm nuxi preview.

Adding this to the reproduction app.vue fixes the issue.

It does indeed resolve it on client side, but in server side the user is still unauthenticated.

@GreenmeisterDavid
Copy link

I'm experiencing this issue as well; prod env, using local provider, the cookie disappears on reload on Firefox, while everything seems fine on Chromium-based browsers.

@Jonathanthedeveloper
Copy link

Jonathanthedeveloper commented May 29, 2024

I noticed that this issue only occurs when you set the baseUrl property in your nuxt.config.ts to a different domain from your nuxtjs frontend.

@taharehany
Copy link

taharehany commented Jun 8, 2024

@jorni-moddit After long and painstaking research, I found this:

const headers = useRequestHeaders(['cookie']) as HeadersInit
const { data } = await useFetch('/api/example', { headers })

this will set cookies from the client side to the request you want in the Nuxt server side

@andre-silva9975
Copy link

andre-silva9975 commented Jun 12, 2024

I am having the same problem. I am also using local provider. Everything works in development and production mode while in localhost. But when I build the app in a remote server that serves as a reverse proxy (using nginx) between the client and the app running in the same server at localhost, every time I log in and reload the page, I am redirected to the login page after a few seconds and the access_token cookie disappears. Here is my configuration:

`
auth: {

baseURL: "/api/auth",
globalAppMiddleware: true,
provider: {
  type: "local",
  endpoints: {
    signIn: { path: "/login", method: "post" },
    signOut: { path: "/logout", method: "post" },
    getSession: { path: "/user", method: "get" }
  },
  pages: {
    login: "/login"
  },
  token: {
    signInResponseTokenPointer: "/token/accessToken",
    sameSiteAttribute: "lax",
  },
},

}
`

@andre-silva9975
Copy link

I am having the same problem. I am also using local provider. Everything works in development and production mode while in localhost. But when I build the app in a remote server that serves as a reverse proxy (using nginx) between the client and the app running in the same server at localhost, every time I log in and reload the page, I am redirected to the login page after a few seconds and the access_token cookie disappears. Here is my configuration:

` auth: {

baseURL: "/api/auth",
globalAppMiddleware: true,
provider: {
  type: "local",
  endpoints: {
    signIn: { path: "/login", method: "post" },
    signOut: { path: "/logout", method: "post" },
    getSession: { path: "/user", method: "get" }
  },
  pages: {
    login: "/login"
  },
  token: {
    signInResponseTokenPointer: "/token/accessToken",
    sameSiteAttribute: "lax",
  },
},

} `

I have updated to version 0.8.0-alpha.2 and when I reload the page the user doesn't logged out.

@HELWATANY
Copy link

HELWATANY commented Jul 1, 2024

The issue is related to running your server (development server or on production) in a secure connection, trying the same steps while running localhost without https won't generate the issue, while setting the development server to run on https will cause the problem to occur.

How To Run Your Local Development On HTTPS

1- You can follow this article to generate and set up your locally signed certificate.
2- Copy your certificates and key to project-root-dir/certificates
3- You can add the following environment variable in your .env file

NUXT_DEV_SERVER_CONNECTION_TYPE="https"  # Nuxt Development Server Connection Type: Should be one of [http|https]

4- Update your nuxt.config.ts should look something like this

export default defineNuxtConfig({
  devServer: {
    https:
      process.env.NUXT_DEV_SERVER_CONNECTION_TYPE === 'https'
        ? {
            key: './certificates/localhost.key',
            cert: './certificates/localhost.crt'
          }
        : false
  },
// ... the reset of your nuxt configs
})

It seems that the issue had been fixed starting 0.8.0-alpha.2, I was able to run my development server with secure connection without facing this issue

@fontanes-innatial
Copy link

The issue is related to running your server (development server or on production) in a secure connection, trying the same steps while running localhost without https won't generate the issue, while setting the development server to run on https will cause the problem to occur.

How To Run Your Local Development On HTTPS

1- You can follow this article to generate and set up your locally signed certificate. 2- Copy your certificates and key to project-root-dir/certificates 3- You can add the following environment variable in your .env file

NUXT_DEV_SERVER_CONNECTION_TYPE="https"  # Nuxt Development Server Connection Type: Should be one of [http|https]

4- Update your nuxt.config.ts should look something like this

export default defineNuxtConfig({
  devServer: {
    https:
      process.env.NUXT_DEV_SERVER_CONNECTION_TYPE === 'https'
        ? {
            key: './certificates/localhost.key',
            cert: './certificates/localhost.crt'
          }
        : false
  },
// ... the reset of your nuxt configs
})

It seems that the issue had been fixed starting 0.8.0-alpha.2, I was able to run my development server with secure connection without facing this issue

I tried the partner's solution but it didn't work in my case.

@yamachita0109
Copy link

I tried the same but it didn't work.

    "@sidebase/nuxt-auth": "^0.8.0-alpha.2",
    auth: {
        baseURL: process.env.API_BASE_URL,
        globalAppMiddleware: true,
        provider: {
            type: 'local',
            pages: {
                login: "/login"
            },
            endpoints: {
                signIn: { path: "admin/login", method: "post" },
                signOut: { path: "admin/logout", method: "post" },
                signUp: { path: "admin/login", method: "post" },
                getSession: { path: "admin/user", method: "get" },
            },
            token: {
                signInResponseTokenPointer: "/token",
                type: "Bearer",
                headerName: "Authorization",
                maxAgeInSeconds: 60 * 60 * 24,
                sameSiteAttribute: "lax",
            },
        }
    },

@mtzrmzia
Copy link

I'm facing the same issue, when log in, the cookie set correctly then refresh page and the cookie gets removed.

  • I'm using external backend
  • I set sameSiteAttribute to strict
"@sidebase/nuxt-auth": "^0.8.0"
  auth: {
    baseURL: 'http://external_api.com/api/auth/',
    globalAppMiddleware: true,
    provider: {
      type: 'refresh',
      endpoints: {
        signIn: { path: 'login', method: 'post' },
        signOut: { path: 'logout', method: 'post' },
        signUp: false,
        getSession: { path: 'me', method: 'get' },
        refresh: { path: 'refresh', method: 'post' },
      },
      token: {
        sameSiteAttribute: 'strict',
        signInResponseTokenPointer: '/data/access_token',
        cookieName: 'access_token',
        maxAgeInSeconds: 60 * 60,
      },
      refreshToken: {
        signInResponseRefreshTokenPointer: '/data/access_token',
        cookieName: 'access_token',
        refreshRequestTokenPointer: 'access_token',
        maxAgeInSeconds: 20160 * 60,
      },
      pages: {
        login: '/login',
      },
    },
  },

@Ulrich-Mbouna
Copy link

Same problem

@Ulrich-Mbouna
Copy link

Any Updates ? Please i face this issue

@mhamzamughal86
Copy link

It seems that the issue you're facing with the cookie being removed upon page refresh is due to the SSR (Server-Side Rendering) nature of the application.

To resolve this issue, you can disable SSR for your application by setting ssr: false in the nuxt.config.ts file. This will make your application run as a Single Page Application (SPA), ensuring that the cookie is available and preserved across page refreshes.

export default defineNuxtConfig({ ssr: false, // other configurations })

@Ulrich-Mbouna
Copy link

It seems that the issue you're facing with the cookie being removed upon page refresh is due to the SSR (Server-Side Rendering) nature of the application.

To resolve this issue, you can disable SSR for your application by setting ssr: false in the nuxt.config.ts file. This will make your application run as a Single Page Application (SPA), ensuring that the cookie is available and preserved across page refreshes.

export default defineNuxtConfig({ ssr: false, // other configurations })

I tried it and it solve the issue, but i'm asking myself if it's not a bad idea to disable ssr in nuxt application. 🤔

@HELWATANY
Copy link

HELWATANY commented Aug 9, 2024

It seems that the issue you're facing with the cookie being removed upon page refresh is due to the SSR (Server-Side Rendering) nature of the application.

To resolve this issue, you can disable SSR for your application by setting ssr: false in the nuxt.config.ts file. This will make your application run as a Single Page Application (SPA), ensuring that the cookie is available and preserved across page refreshes.

export default defineNuxtConfig({ ssr: false, // other configurations })

This can not be considered a solution if your main goal is to create an SSR application!

@HELWATANY
Copy link

HELWATANY commented Aug 9, 2024

@yamachita0109 @mtzrmzia If you are serving your app over a secure connection (using HTTPS), please consider setting secureCookieAttribute to true, please check here

  auth: {
    baseURL: 'http://external_api.com/api/auth/',
    globalAppMiddleware: true,
    provider: {
      type: 'refresh',
      endpoints: {
        signIn: { path: 'login', method: 'post' },
        signOut: { path: 'logout', method: 'post' },
        signUp: false,
        getSession: { path: 'me', method: 'get' },
        refresh: { path: 'refresh', method: 'post' },
      },
      token: {
        sameSiteAttribute: 'strict',
        signInResponseTokenPointer: '/data/access_token',
        cookieName: 'access_token',
        maxAgeInSeconds: 60 * 60,
        secureCookieAttribute: true, // <---- you need to add this, default is false and should be false if you are serving over HTTP
      },
      refreshToken: {
        signInResponseRefreshTokenPointer: '/data/access_token',
        cookieName: 'access_token',
        refreshRequestTokenPointer: 'access_token',
        maxAgeInSeconds: 20160 * 60,
        secureCookieAttribute: true, // <---- you need to add this, default is false and should be false if you are serving over HTTP
      },
      pages: {
        login: '/login',
      },
    },
  },

@vincepaquette
Copy link

Any update on this please ? Did anyone figure it out ? Disabling the SSR isn't a solution in my case

@cip8
Copy link
Contributor

cip8 commented Aug 26, 2024

Any update on this please ? Did anyone figure it out ? Disabling the SSR isn't a solution in my case

Have you tried the new version (0.9.1) & experiencing the same issues?

@HELWATANY
Copy link

Any update on this please ? Did anyone figure it out ? Disabling the SSR isn't a solution in my case

Have you tried the new version (0.9.1) & experiencing the same issues?

@cip8
I wasn't able to regenerate the issue since version 0.8.0-alpha.2

@Ulrich-Mbouna
Copy link

Any update on this please ? Did anyone figure it out ? Disabling the SSR isn't a solution in my case

Have you tried the new version (0.9.1) & experiencing the same issues?

@cip8 I wasn't able to regenerate the issue since version 0.8.0-alpha.2

So your problem is solved?

@HELWATANY
Copy link

Any update on this please ? Did anyone figure it out ? Disabling the SSR isn't a solution in my case

Have you tried the new version (0.9.1) & experiencing the same issues?

@cip8 I wasn't able to regenerate the issue since version 0.8.0-alpha.2

So your problem is solved?

I was trying to help by providing reproduction steps and a fix if needed 🙂

@josselinonduty
Copy link

josselinonduty commented Sep 4, 2024

I still get this issue on v0.9.1.

I have tried a few different setups, like using h3 as my session provider, and using nuxt-auth endpoints/token. Sometimes it does work, but it seems not to be reliable.

I'll edit my message in a few hours and provide my config or a reproduction if I can.

@josselinonduty
Copy link

josselinonduty commented Sep 4, 2024

I still get this issue on v0.9.1.

I have tried a few different setups, like using h3 as my session provider, and using nuxt-auth endpoints/token. Sometimes it does work, but it seems not to be reliable.

I'll edit my message in a few hours and provide my config or a reproduction if I can.

Okay, so I got it working.
Here is what I found:

Before:

export default defineEventHandler(async (event) => {
    const token = getCookie(event, "session");
    // business logic here
});

The issue is that the cookie is not sent reliably or there is something I don't understand.
What I can confirm is that I get session undefined when I reload the page manually (hence it invalidates the client cookie because throw an error when it's invalid).

After:

export default defineEventHandler(async (event) => {
    const authorization = event.headers.get("Authorization");
    const token = authorization?.split("Bearer ")[1];
});

Now I get the token reliably and can use it.

Conclusions:
There might be an issue (or a conflicting intended behaviour) in Nuxt(-Auth) lifecycle that doesn't pass cookies or not at the right time on manual reload, hence it is undefined. I could be totally wrong tho.

@samuelemusiani
Copy link

samuelemusiani commented Sep 20, 2024

To resolve this issue, you can disable SSR for your application by setting ssr: false in the nuxt.config.ts file. This will make your application run as a Single Page Application (SPA), ensuring that the cookie is available and preserved across page refreshes.

export default defineNuxtConfig({ ssr: false, // other configurations })

I have encountered this issue too. Disabling ssr fixed for me

@dasmoro
Copy link

dasmoro commented Oct 11, 2024

In my case changing maxAgeInSeconds of token from 30 to 21 days was fixed such problem. With 30 days value cookie set only with 1 second expire. I don't know, why. And didn't find any documentation of this.
Скриншот 11-10-2024 142433

@rmnaderdev
Copy link

Hi all. I also wanted to chime in and say that I too am facing this issue on v0.9.3. I am in the middle of moving a Vue app to Nuxt in order to use SSR to support SEO better for my product so turning SSR off is not an acceptable fix in my situation. I am trying to use my existing .NET backend auth with the new Nuxt frontend (JWT tokens with refresh tokens). I am able to login and make API calls but, like others have said, the auth cookie is removed once I refresh the page with the following console error.

image
image

I thought maybe the issue was cors or an https issue, but I have already turned on...

Okay so as I am typing out this, I realized that I did not add the NODE_TLS_REJECT_UNAUTHORIZED=0 variable to my .env file like I did with my other proof-of-concept project and the reason SSR was not able to get the user was because my .NET self-signed SSL cert was not trusted by the node backend when calling the endpoints on the server side...

So it appears that I am no longer having this issue. I hope this helps someone else!

@ZenelShabani
Copy link

God this is frustrating, can someone plx look into this. Im getting the same issue on 0.9.3.

Cookie is being set, and then deleted as soon as one refreshes.

@mikolajszymczuk1
Copy link

Any new state of this bug ?

@mikolajszymczuk1
Copy link

mikolajszymczuk1 commented Oct 17, 2024

I have simple solution , you can enable option (disableServerSideAuth: true). this is the solution at this moment cookie stay after refresh my backend response correct header Set-cookie so thats great but this is not the solution for general problem . Im trying to find solution deeper.

@julienguillot77
Copy link

julienguillot77 commented Oct 23, 2024

@mikolajszymczuk1
I'm facing the same issue so I tried your solution but when I set the config to disableServerSideAuth: true, I have infinite redirect loop from '/session' to '/auth/login'.
Btw, if you don't create a /session route, you got an error when accessing to 'auth/login' page.

@julienguillot77
Copy link

It seems that set the token cookie's httpOnlyCookieAttribute value to false makes persisting the cookie even after reloading.
When set to true, the cookie is kind of hidden or stored somewhere else. I would like to make this cookie httpOnly. Is a fix could possibly be made ?

@mikolajszymczuk1
Copy link

@julienguillot77 let me see but what I observed for example when I set cookie domain in nuxt settings , cookie exists after refresh

@mikolajszymczuk1
Copy link

Only problem that still exists is the problem with get session from token after refresh but when I console logs things in source code it's look like logic has everything that is require so maybe bug maybe nuxt config for nuxt auth require to set some properties

@wpoPR
Copy link

wpoPR commented Nov 18, 2024

any news about this?

@dolphinwow
Copy link

I have the same problem. Is it still not fixed?

@mikolajszymczuk1
Copy link

@dolphinwow there are not new updates, im waiting with my auth refactor but i think i will kick this lib to trash and implement own auth logic.

@mikolajszymczuk1
Copy link

last information that i have is that this is not problem with cookie , i changed config, i added few options from nuxt auth docs and finally cookie exists after refresh page. After some exploration in source code i found there is a strict problem with getting session after refresh, its something like logic correctly load data to variables but there is error when lib makes request

@mikolajszymczuk1
Copy link

later i will setup this repo and i will try to debug this error, I have some idea when can be the problem

@uricholiveira
Copy link

Any news? Still having this problem using version: 0.9.4

@cyprille
Copy link

Hi everyone and many thanks for this very cool library!

I'm experiencing the exact same issue as everyone one here since August. I struggled hours/days to make it work, but without any luck, trying all updates since then...

As a turnaround, I disabled SSR, but I'm hoping this could be fixed some time to work out of the box, as it's a big downside to be forced to disable SSR.

If I can help to resolve it, feel free to contact me 🙏🏻

@mikolajszymczuk1
Copy link

@cyprille hi , if you whould like to help , you can help me with debugging, try to setup project and what i know is the problem exists on external api, i tested everything on playground and with api created on nitro side session works correcltry but when logic must refresh session after refresh page on our external api there is error in request call function. Im working on this bug today, this is terrible but if we fix it it will not force the most developers to switch to own auth logic

@cyprille
Copy link

cyprille commented Dec 17, 2024

@mikolajszymczuk1 Hi, thank you for your reply! Yes, I already have a project setup to reproduce this issue, but it's a private repo, so I won't be able to share it.

It's easy to reproduce it with an external backend for auth with this kind of config:

  auth: {
    isEnabled: true,
    baseURL: '/api',
    provider: {
      type: 'local',
      endpoints: {
        signIn: {
          path: '/login',
          method: 'post',
        },
        getSession: {
          path: '/session',
          method: 'get',
        },
      },
      session: {
        dataResponsePointer: '/',
        dataType: {
          id: 'number',
          firstname: 'string',
          lastname: 'string',
          email: 'string',
        },
      },
      token: {
        signInResponseTokenPointer: '/token',
        type: 'Bearer',
        cookieName: 'auth.token',
        headerName: 'Authorization',
        maxAgeInSeconds: 50400,
        sameSiteAttribute: 'none',
        secureCookieAttribute: true,
        httpOnlyCookieAttribute: false,
      },
      refresh: {
        isEnabled: true,
        endpoint: {
          path: '/refresh',
          method: 'post',
        },
        refreshOnlyToken: true,
        token: {
          signInResponseRefreshTokenPointer: '/refresh_token',
          refreshRequestTokenPointer: '/refresh_token',
          cookieName: 'auth.refresh_token',
          maxAgeInSeconds: 50400,
          sameSiteAttribute: 'none',
          secureCookieAttribute: true,
          httpOnlyCookieAttribute: false,
        },
      },
    },
    globalAppMiddleware: true,
  },

As you can see, I tried to set up a lot of configs here, following the documentation.
I also tried to restart from basic config to this point without any luck, testing each new parameter individually.

Hope this helps to debug!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug that needs to be resolved help-needed Action needed: The help of the community would be appreciated p3 Minor issue provider-local An issue with the local provider
Projects
None yet
Development

No branches or pull requests