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

Losing Authenticated State on Page Refresh #6

Closed
J0Sepff opened this issue Nov 20, 2023 · 21 comments
Closed

Losing Authenticated State on Page Refresh #6

J0Sepff opened this issue Nov 20, 2023 · 21 comments
Assignees

Comments

@J0Sepff
Copy link

J0Sepff commented Nov 20, 2023

Hello! I'm using the latest version of nuxt-auth-sanctum, but the problem of losing authorization when refreshing the page persists.

image
image
image

Nuxt config:

export default defineNuxtConfig({
  devtools: { enabled: false },
  css: ["assets/styles/common.scss"],
  modules: [
    "@nuxtjs/eslint-module",
    "@nuxtjs/tailwindcss",
    "@vueuse/nuxt",
    "@pinia/nuxt",
    "nuxt-swiper",
    "nuxt-auth-sanctum",
  ],
  ssr: false,
  app: {
    pageTransition: { name: "page", mode: "out-in" },
  },
});

Nuxt ENV:

NUXT_PUBLIC_SANCTUM_BASE_URL=http://10.0.1.6/api/v1
NUXT_PUBLIC_SANCTUM_ORIGIN=http://10.0.1.6:3000
NUXT_PUBLIC_SANCTUM_ENDPOINTS_CSRF=http://10.0.1.6/api/csrf-cookie
NUXT_PUBLIC_SANCTUM_ENDPOINTS_USER=/user
NUXT_PUBLIC_SANCTUM_REDIRECT_KEEP_REQUESTED_ROUTE=true

Laravel ENV:

SESSION_DOMAIN=10.0.1.6
SANCTUM_STATEFUL_DOMAINS=10.0.1.6:3000

If I turn on SSR, the following error appears:
image

@manchenkoff
Copy link
Owner

Hey @J0Sepff, error is not related to the package since I do not use pinia, probably you forgot to exclude reactive values with localStorage during the hydration by using skipHydrate(variable). Could you check with SSR enabled and adjusted Pinia store?

In the meantime, I will try to setup a playground without SSR to make sure that authentication state stays the same after reload.

@J0Sepff
Copy link
Author

J0Sepff commented Nov 20, 2023

@manchenkoff Thanks for the answer. You're right, the mistake with SSR is on my side. Authorization is saved if I use SSR, but if SSR: false, then authorization losing after refreshing the page. If necessary, we can contact you and show you a demo.

@manchenkoff
Copy link
Owner

Published new v0.0.11 version, @J0Sepff please try with this one, hope problem is solved

@manchenkoff manchenkoff self-assigned this Nov 20, 2023
@J0Sepff
Copy link
Author

J0Sepff commented Nov 20, 2023

@manchenkoff Problem solved! Thank you!

@J0Sepff J0Sepff closed this as completed Nov 20, 2023
@manchenkoff
Copy link
Owner

Great! I guess it also was related to #4, thanks for the additional details @J0Sepff 👍

@jjjrmy
Copy link

jjjrmy commented Jan 21, 2024

I'm still having this issue where if you login and go to a guarded page, then refresh the page, it will show you the login prompt briefly before refreshing.

I am hosting this on Cloudflare Pages and have ssr: true

https://nuxt.likewizard.com/
johndoe@example.com
secret

@manchenkoff
Copy link
Owner

@jjjrmy let's continue the conversation in #25 since I believe it's also related

@jjjrmy
Copy link

jjjrmy commented Jan 23, 2024

@jjjrmy let's continue the conversation in #25 since I believe it's also related
This problem is unrelated to that issue.

I think specifically this is an issue with Nuxt + Cloudflare Pages hosting. I hosted the same repo on Digital Ocean App Services, and there is no issue with the login state. So makes me think it is some sort of rendering / environment issue with that hosting provider.

@alecritson
Copy link

I realise this is an old issue but wanted to share my experience with this (which I'm certain is related).

From what I can figure out is that the Cloudflare workers disable the credentials field, see: cloudflare/workers-sdk#2514

What led me there was checking the server logs on nuxt admin and seeing:

the 'credentials' field on 'requestinitializerdict' is not implemented.

I tested this theory out by hosting on Vercel and everything worked straight away.

@manchenkoff
Copy link
Owner

Thanks @alecritson for the insight! I think it might save someone's day 😄

@alecritson
Copy link

Ok so just to follow up, I found this thread here: sindresorhus/ky#366 which mentions about setting credentials to undefined if it's not supported.

I'm not a JS expert by any stretch but would something like this even work? (just copying from the PR related to that issue)

const isCredentialsSupported = 'credentials' in Request.prototype;

await $fetch(config.endpoints.csrf, {
    baseURL: config.baseUrl,
    credentials: isCredentialsSupported ? 'include' : undefined,
});

I was trying to test myself with yarn link but I couldn't get it to play ball 😅

@manchenkoff
Copy link
Owner

@alecritson I'm not sure either 😄 For sure I can test a positive case, but I would need someone's help with testing it in the actual environment like Cloudflare. Just in case, will you be up for that?

@alecritson
Copy link

That'd be awesome if you could, I have Cloudflare pages all set up and ready to give it a spin 🙏

@manchenkoff
Copy link
Owner

Awesome, thanks! I'll try to open a PR in a next couple of days 👍

@manchenkoff
Copy link
Owner

Hey @alecritson, published new 0.4.1 version, please try it in your app

@alecritson
Copy link

Thanks @manchenkoff

I had a little play and it certainly stopped the issue from coming up but I think it creates a new 🤔

I tested on a Vercel deployment and Cloudflare. Same app, same domains, just switching the DNS out in Cloudflare.

Cloudflare now it doesn't set the cookies on page load, I assume because their workers don't support it so they don't get set on the server request. Going to login, even though the csrf-cookie endpoint is hit before login there is a CSRF token mismatch error.

Vercel does set them on page load and login works as expected, however, if I remove the cookies after the page load and go to login the same issue arises as Cloudflare.

image

Could it be that even though it's calling csrf-cookie beforehand it's not using the values set in time for the login request to happen? 🤔

@manchenkoff
Copy link
Owner

manchenkoff commented Jun 19, 2024

Going to login, even though the csrf-cookie endpoint is hit before login there is a CSRF token mismatch error.

Usually, it happens due to cookie domain misconfiguration between CSR/SSR/Laravel. Could you please double-check that the cookie domain is in a format like .domain.coom and CSRF header equals the cookie from sanctum/csrf-cookie response in the browser?

Could it be that even though it's calling csrf-cookie beforehand it's not using the values set in time for the login request to happen? 🤔

Yes, especially when the domain is different. For example, if a cookie is set for domain api.domain.com (instead of .domain.com) but nuxt is on domain.com then it will not pass this cookie to the API request. And also, the Origin URL should be in a stateful domain list.

@alecritson
Copy link

Yeah so the Cookie domain is .domain.com and if I load the page up in Vercel the cookies are set on load then I can see the XSRF token header is passed to the login...

image

Which logs me in fine and I can refresh the page and the state is maintained. If I then clear the cookies in dev tools and submit the login form without refreshing, the XSRF token isn't sent on the subsequent login endpoint, even after the csrf-cookie endpoint.

image

@manchenkoff
Copy link
Owner

I see, thanks for the explanation @alecritson.

In this case I assume manual deletion somehow interferes with Nuxt useCookie state because it wouldn't call csrf-cookie endpoint if it was defined, but it looks like even when we get a cookie value, it is not updated later. I will try to also reproduce this behavior with manual delete.

Except this, does it work fine with page refresh and all other things?

@alecritson
Copy link

Yeah I'm not too sure because because in Cloudflare's instance the cookies are never set on page load due to credentials being disabled and it suffers from the same issue as the Vercel app.

So it seems if the cookies aren't set then on page load they never go into subsequent requests even though they do get set in the browser. But when the page is refreshed the cookies are overwritten and the app starts working as expected.

Once logged in though everything is perfect.

@manchenkoff
Copy link
Owner

Okay, I'll work on that. Thanks a lot @alecritson for your help with the debugging, I'll let you know if I find some solution to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants