Closed maksimdrosdov closed 1 year ago
This doesn't look like a Nuxt bug. Can you provide a minimum reproduction?
I believe that happens because you need to connect your pinia instance with app store.
In your vue components pinia can get store context from app's context (this.$store) via some magic, but there is no such a thing in a simple general function. But you can get it from ctx.app.$store
Sadly I've not worked with pinia closely, but I guess a little trick from Vuex-smart-modue might help you to find easy solution, You need to connect you store manager with store context manually:
// vuex-smart-module example
// Get module context
const ctx = yourModule.context(store);
So if there is no such a thing for pinia, there is an issue in the pinia lib.
And actually we can find similar issue there
console.log('loggedIn = ', loggedIn);
shows that true, but everything exactly redirects to auth
@danielroe sent an invite
@maksimdrosdov Please be aware that a full-blown project is no reproduction 🙈
The goal is to have as little "moving pieces" as possible and a project that is as small as possible to reproduce the bug so contributors can pin it down easily and it is not caused by any custom userland logic
console.log('loggedIn = ', loggedIn);
shows that true, but everything exactly redirects to auth
There might be a little trick with lifecycle and browser's logs..
Try to do smth like this to clear link to store's object
const authState = useAuthStore();
console.log({...authState});
And check your loggedIn
in exact moment
import { storeToRefs } from 'pinia';
import { useAuthStore } from '~/store/auth';
export default defineNuxtRouteMiddleware(() => {
const authStore = useAuthStore();
console.log({...authStore});
const { loggedIn } = storeToRefs(authStore);
if (!loggedIn.value) {
//return navigateTo('/auth');
}
});
This problem is still there please fix it. In middleware pinia data is empty
@typhoon11 Can you provide a reproduction?
@typhoon11 Can you provide a reproduction?
So I made a getter in pinia and tried them on middleware and a page
So it's visible that pinia is empty for the files in the middleware directory
@typhoon11 Please provide a repository or use Stackblitz or Codesandbox as linked above. This is the best way to make it easy for maintainers to help you. I highly recommend to read the linked paragraph above.
@typhoon11 Please provide a repository or use Stackblitz or Codesandbox as linked above. This is the best way to make it easy for maintainers to help you. I highly recommend to read the linked paragraph above.
Sorry for late reply. I tested it and found it works on normal page redirect but when we refresh the page it becomes unavailable. I attach the stack blitz below https://stackblitz.com/edit/github-nf9a2f
@typhoon11 In your middleware, you should not trigger navigateTo
in the "default"/"happy" case. Instead, just not return anything and the middleware will "succeed".
import { useDiscordUser } from '~/stores/auth';
export default defineNuxtRouteMiddleware(async (to, from) => {
const app = useNuxtApp();
const user = await useDiscordUser(app.$pinia);
if (!user.user) {
console.log('User not logged in');
return navigateTo('/');
}
});
@typhoon11 In your middleware, you should not trigger
navigateTo
in the "default"/"happy" case. Instead, just not return anything and the middleware will "succeed".import { useDiscordUser } from '~/stores/auth'; export default defineNuxtRouteMiddleware(async (to, from) => { const app = useNuxtApp(); const user = await useDiscordUser(app.$pinia); if (!user.user) { console.log('User not logged in'); return navigateTo('/'); } });
In my actual code if the user is not logged in I have to send the user to an external api for login so I need navigateTo for that
@typhoon11 Yes, that's fine. But before, you called navigateTo
in both cases, if the user exists and not. in the default case (logged-in), you should not ☺️
@typhoon11 Yes, that's fine. But before, you called
navigateTo
in both cases, if the user exists and not. in the default case (logged-in), you should not ☺️
Nope it didn't fixed on doing refresh the data becomes null my code:
You don't even need the else
and return there.
Be aware that the middleware is executed on server on the first request (and no window
will be available there)
You don't even need the
else
and return there.Be aware that the middleware is executed on server on the first request (and no
window
will be available there)
Even if I remove the else it's the same, like when I am doing page navigation the pinia data is there and it allows me to open but whenever I press refresh on that page the data is gone
You don't even need the
else
and return there.Be aware that the middleware is executed on server on the first request (and no
window
will be available there)
I am guessing the pinia code I have written is wrong, can you help me with that?
export const useDiscordUser = defineStore('discord_user', {
state: () => {
return {
user: null as UserPartial | null
}
},
getters: {
isUserLoaded: (state) => {
return state.user !== null
}
}
})
Doesn't look wrong to me but depends how you fetch the user. I've adapted your example. When you switch the user as null/actual user, you see the middleware works as expected
Doesn't look wrong to me but depends how you fetch the user. I've adapted your example. When you switch the user as null/actual user, you see the middleware works as expected
I am fetching the user details from an external API and that's done in the header component, so when the page loads and the middleware gets initiated the user value becomes null, so I had to save the user details as local storage and keep the pinia data hydrated.
I am fetching the user details from an external API and that's done in the header component, so when the page loads and the middleware gets initiated the user value becomes null, so I had to save the user details as local storage and keep the pinia data hydrated.
The server has no access to localstorage as mentioned above. Instead, you could e.g. use a cookie or do the request in the middleware instead?
I allow my self to re-open this ticket since the problem has not been solved yet!
@alouimohamedhabib instead, open a new issue with a reproduction! Thanks ☺️
import { useAuthStore } from '~/stores'
export default defineNuxtRouteMiddleware((to, from) => {
const authStore = useAuthStore()
const authenticated = computed(() => authStore.isAuthenticated())
if (!authenticated) {
return navigateTo('/login')
}
})
Had the same issue, and solved with @InochiSoft solution but adding .value
import { useUserStore } from "~/stores/modules/user";
export default defineNuxtRouteMiddleware((to, from) => {
const userStore = useUserStore();
const authenticated = computed(() => userStore.isAuthenticated())
if (!authenticated.value) {
return navigateTo('/login');
}
});
I hope someone finds it useful
try chck if process.server
is true
some like this
export const requireAuth = defineNuxtRouteMiddleware((to, from) => {
const userStore = useUserStore();
// since userStore only exist in client. ignore server side
if (process.server) {
return
}
if (userStore.isLogin) {
return
}
if (to.path !== "/admin/login") {
return navigateTo('/admin/login')
}
})
found a solution. might help
added userStore.$subscribe((cb) => cb.events)
import { useUserStore } from '~/stores/userStore';
export default defineNuxtRouteMiddleware(() => {
const userStore = useUserStore();
userStore.$subscribe((cb) => cb.events)
const isAdmin = computed(() => userStore.isAdmin)
if (!isAdmin.value) {
return navigateTo('/');
}
});
@marianharnageaq, This will be checked every time the pinia state changes. If, for example, you change the user’s name, he will be immediately redirected to the Index page
Same problem here.
The middleware with firebase (or vuefire example)
For example, in this example where if implemented, redirects the user to the login page if not logged in:
// middleware/auth.ts
export default defineNuxtRouteMiddleware(async (to, from) => {
const user = await getCurrentUser()
// redirect the user to the login page
if (!user) {
return navigateTo({
path: '/login',
query: {
redirect: to.fullPath,
},
})
}
})
will work navigating normally, but won't work if you reload the page from the browser, it will asume there is no user logged in even if there is, and it's because it does not wait firebase to log the user, so is null or undefined and fails and redirects to login page even tho there is an user logged in
Environment
middleware
Reproduction
middleware
Describe the bug
When I reload the page, it throws me to the authorization page, although the user is authorized
Additional context
No response
Logs
No response