State leaking between concurrent sessions when useStore comes after an await on SSR #2159
Replies: 5 comments 2 replies
-
You should indeed call useStore before the await or pass the pinia instance to avoid sharing the state across request. This is already documented. Improvements to docs are welcome though 🙌 |
Beta Was this translation helpful? Give feedback.
-
I don't agree, at least the documentation is not clear enough in the examples. |
Beta Was this translation helpful? Give feedback.
-
It would be nice if there at least where something that can warn us rookie developers from making this mistake. Would it for example be possible to create an eslint rule or something? |
Beta Was this translation helpful? Give feedback.
-
@posva if one wants (or somehow needs, e.g. stores are lazy loaded) to call import { defineStore, getActivePinia } from 'pinia'
import { useUserStore } from './user'
export const useCartStore = defineStore('cart', {
actions: {
async orderCart() {
// get currently active Pinia instance
const pinia = getActivePinia();
try {
await apiOrderCart(user.token, this.items)
// explictly pass Pinia instance to useStore
const otherStore = useOtherStore(pinia)
// another action
this.emptyCart()
} catch (err) {
displayError(err)
}
},
},
}) |
Beta Was this translation helpful? Give feedback.
-
@erikmode Very crude check can be made with ESLint AST selectors and This only works if you call your stores |
Beta Was this translation helpful? Give feedback.
-
We have encountered this a few times, and I think really it's important to know about because it's hard to test and and an easy mistake to make. It can easily leak user data if not handled correctly.
Solution is to allways pass the pinia instance. How can we solve passing the pinia instance all the way to the API-functions in the example ?
Reproduction link
https://github.com/iPrytz/vue3-pinia-ssr-example
Steps to reproduce
userStore
andmyDataStore
useUserStore().sessionId
useUserStore().sessionId
againconst store = useUserStore()
andstore.sessionId
is used both before and after await, but in more complex cases it can still be a missmatch.For example, in our store, we fetch specific user data connected to the sessionId, but before we do that we need to fetch and await the users profile settings, then we can fetch the specific user data. From our store we call the API and in the API-handler we then add the sessionId/token from userStore, and now we have a missmatch because we do
useUserStore()
after theawait user profile
while we have multipe requests comming in to our node server. So the sessionId/token added to the request is now from another user and we get mixed up data.I added a repo to reproduce the problem, instructions how to test this is found in the README
Would also love to get some explanation on what is actually hapening here that is causing this behavior.
Thank you to everyone working on this project, you're awesome!! 💯 🙌
Beta Was this translation helpful? Give feedback.
All reactions