I have an authentication on my nuxt web-app, using the nuxt/auth module. I also use modular vuex stores to handle different states. After I login, everything is fine and I can navigate through the app normally. But when I try to reload the page or access it directly through a URL, the user is not accessible, thus, the whole web-app becomes unusable. I try to access the user object with this.context.rootState.auth.user
, which is null after page-reload or direct access. Strangely enough, this only happens in production.
I already tried to add an if-guard, but sadly the getter is not reactive. Probably because it´s a nested object. This is my current getter:
get someGetter() {
if (!this.context.rootState.auth.user) {
return []
}
const userId = this.context.rootState.auth.user.id as string
const arr = []
for (const item of this.items) {
// Using userId to add something to arr
}
return arr
}
Is there a way to force nuxt to finish the authentication before initialising the vuex-modules, or to make this getter reactive, so it will trigger again, when the user object is accessible?
This is what my auth-config looks like in nuxt.config.ts:
auth: {
strategies: {
local: {
_scheme: '@/auth/local-scheme',
endpoints: {
login: {
url: '/api/authenticate',
method: 'post',
propertyName: false
},
logout: { url: '/api/logout', method: 'post' },
user: { url: '/api/users/profile', propertyName: false }
}
},
// This dummy setting is required so we can extend the default local scheme
dummy: {
_scheme: 'local'
}
},
redirect: {
logout: '/login'
}
}
EDIT
I resolved this by following Raihan Kabir´s answer. Using vuex-persistedstate in an auth-plugin, which is triggered every time the server renders the page. The plugin saves the userId in a cookie, so the store can use it as a fallback, if the auth-module isn´t ready.
Wondering about Authentication In Vue Using Vuex? We can help you. We have seen customers use local storage to manage tokens generated through client-side authentication. Vuex serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.
To help with that, Vuex allows us to divide our store into modules. Each module can contain its own state, mutations, actions, getters, and even nested modules - it's fractal all the way down: Inside a module's mutations and getters, the first argument received will be the module's local state.
The login action passes the Vuex commit helper that we use to trigger mutations. We could store the token in vuex store, but if the user leaves our application, all of the data in the vuex store disappears.
We have now defined the attributes of the state. Now the Vuex state will hold our authentication status, jwt token, and user information. We use Vuex actions to commit mutations to the vuex store. To create a login action, we open the ./src/store.js file and add the following to the actions object:
The thing is, the vuex
clears data on reload/refresh to keep credentials secure. That's what vuex
is. If you want to store data for long time without being interrupted after reloading, you should use localstorage for that. But localstorage is not recommended for storing credentials.
If you need only user_id
to keep in the vuex
, use Cookie instead. And try something like this in your store's index.js
file -
export const actions = {
// This one runs on the beginning of reload/refresh
nuxtServerInit ({ commit }, { req }) {
if (req.headers.cookie) {
const parsed = cookieparser.parse(req.headers.cookie)
try {
// get user id that you would set on auth as Cookie
user_id = parsed.uid
} catch (err) {
// error here...
}
}
// perform login and store info on vuex store
commit('authUserOnReload', user_id)
},
}
// Define Mutations
export const mutations = {
authUserOnReload (state, user_id) {
// perform login here and store user
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With