Pinia state leaks across browser sessions
I have a pretty severe issue where data stored in Pinia is sometimes leaked across requests. I have a store that is persisted in cookies using the @pinia-plugin-persistedstate package. The state of this is sometimes set across all users so all users have the same pinia data. Even though their cookies are empty, when looking at the state is set to that of another user.
Any idea's how this can accur?
32 Replies
do you use pinia in your plugins?
I do use it in a plugin that wraps the basic $fetch to always send the authentication headers along with it like follows:
Considering your point, I assume this is not SSR safe than?π
Is there another way I should call useAuthStore()?
Would passing the pinia instance to the store as follows fix this issue @manniL / TheAlexLichter
Thatβs what Iβd suggest
Thank you so much man!
We unfortunately encountered the same issue so this didn't seem to be the fix. Do you maybe have any other idea's that could cause this? It's very hard to reproduce this since it only happens once in a while and I am not sure what circumstances cause this to happen.
@RicharDVD Do you define and import your default state from a separate file?
@Dovendyret The store looks as follows:
This is where the default state is set.
seems like this might be a bug in
piniaPluginPersistedstate.cookies
FWIW, I use this plugin and haven't seen this behavior of cookie sharing between users.
@RicharDVD Are you using the Nuxt module? It should be declared in your
modules
config as '@pinia-plugin-persistedstate/nuxt',
I set the persist config on a store like so:
I do indeed use the nuxt module. It is very hard to reproduce since it happens only happens occasionally. For now, I decided to just use a custom composable where the state is stored with instead of a pinia store. See if we will run into it again. If so, it must be something completely different.
Only thing I could think of was the fact that I access useAuthStore within the onRequest and onResponseError callback. That that might be the reason but not sure
I'm just curious - my config uses
persistedstate
but yours uses piniaPluginPersistedstate
where are you defining piniaPluginPersistedstate
?I think that is because you are using an older version of the module. Since 4.0.0 it has updated to piniaPluginPersistedstate (https://github.com/prazdevs/pinia-plugin-persistedstate/releases/tag/v4.0.0)
GitHub
Release v4.0.0 Β· prazdevs/pinia-plugin-persistedstate
π Enhancements
Support excluding paths from persistence with omit option
Support autocompletion for dot-notation paths in pick and omit options
β οΈ Rehydrate only picked/omitted paths (when specifi...
hmmm - I don't actually have that in my package.json - I just use:
"@pinia-plugin-persistedstate/nuxt": "^1.2.1",
which is the most recent version of that module
That is because they moved the module
appears to use 4.1.1
If you look in their docs, they now say that the npm package is "pinia-plugin-persistedstate".
https://prazdevs.github.io/pinia-plugin-persistedstate/frameworks/nuxt.html
Usage with Nuxt | Pinia Plugin Persistedstate
Configurable persistence of Pinia stores.
Yeah, odd - the docs seem to use both...
well now I am scared to change what's working! π
I just tested a few different users in different incognito tabs - no pinia state shared
so yeah, something must be getting written and persisted to your store in an unusual way
The thing is, the same for meπ
It happens only occasionally
That is what makes it so hard
Do you have any routeRules? Where your state is being cached?
I do use isr on some routes
if you are caching state on the instance, its possible that if it's leaking
that might be the issue
Caching has been tricky, as my app (probably like yours) has lots of static content, but then also a user, with login state and a header with their name/avatar/data
so if you use isr or swr, it ends up caching the user state
Maybe wrapping all user-specific content in ClientOnly would circumvent that, but I'm not sure
I think you might be right. But let's say I make the navbar client only (which uses some auth logic) it would jump into the page which is not so nice. I think I'd have to just remove the cache rules and see if that works out.
it would. But I'd guess it'd be easier to cache the data in the Nitro API granularly
instead of caching the whole SSR'd page
also outlined that in https://www.youtube.com/watch?v=Zli-u9kxw0w I think - or one of the other videos π
Alexander Lichter
YouTube
What is BFF?! (With Nuxt, Nitro and h3)
π 10$ off for Michael's Nuxt Tips Collection with the following link and code DEJAVUE https://michaelnthiessen.com/nuxt-tips-collection?aff=plY9z *
π 10% off for vuejs.de Conf with Code LICHTER https://conf.vuejs.de/tickets/?voucher=LICHTER *
---
Links and Resources:
π Code TODO
π h3 https://h3.unjs.io/
π unstorage https://unstorage.unjs.io/
...
Yeah, I've watched that! I kind of would almost like to see a reverse Server Components option in Nuxt. Where all components are server components, and some select few are Client.
Like, a global config to set all components as server components
I mean, you can do that through .server.vue, also for pages etc.
and use the
nuxt-client
on the ones that are different
Right - but I have like 400+ components π
My use case is that most of the pages I wanted heavily cached
but there are "islands" of user-content that should never be cached
and I was concerned about how performant setting ALL the components to .server.vue might be
but I may experiment with it and seeThank you guys for helping out. I think I will indeed go with this route since it's an easy solution in my case
1 last thing, I have ISR set to 3600 (so 1 hour). Just for my understanding, under what circumstances will the state be leaked since it's hard for me to reproduce?
when the cache expires and a logged-in user requests the page
I did confirm that this was indeed the issueπ Thank you so much!
you should not call
use*
functions within the hooks - instead, call them outside the callback, and use them within it.Thank you for pointing it out. Fixed itπ