Nuxt Vuex Store Cookies Issue

Ivan Zhivolupov picture Ivan Zhivolupov · Jun 14, 2018 · Viewed 9.8k times · Source

Good time of the day!

After a few weeks of development of my project, i've decided to migrate from plain Vue to Nuxt.

Mainly because i need SSR, although i know that Google can execute JS presented on the page and therefore generate appropriate content for their search bot.

Another reason is a general workflow of the project development. I like idea with automatic instantiation of routes, store, etc.

I've faced, however, a pretty strange behavior of the application when it is running in the mode: universal instead of mode: spa. And i don't want to switch to mode: spa since then i lose the SSR i was migrating for in the first place.

I' have an account module in the store - account.js which is responsible for handling any operations related to the account management, such as login/logout, get profile of authenticated user, store the token obtained from the login request as well as the logic for handling the 2FA TOTP procedure.

In my legacy application, i was able to get the token from the cookies by just using the following bit of the code

import Cookies from 'js-cookie';

export const state = {
   user: null,
   token: Cookies.get('token')
}

And save token after the successful authentication by executing the following mutation:

[types.ACCOUNT_SAVE_TOKEN] (state, { token, remember }) {
    state.token = token;
    Cookies.set('token', token, {
      expires: 365,
      httpOnly: true
    });
}

But after migration to Nuxt.js, every time im loggin in, the token value in the state is getting populated, but no cookie is set, and after navigating to the other page inside the project (it is pwa, so no reloading, etc) token is reset back to null.

This issue however is gone if application is switched to the mode: spa from mode: universal and everything is working just fine.

I've read many issues on the github as well as done pretty big portion of crawling throught the websites which are trying to solve the same issue, though none of the suggestions are working for me.

I've even installed the cookie-universal-nuxt package from NPM which claims to be working with the SSR, but yet every time I'm trying to access this.$cookies.get('token') in the state, or anywhere else (mutations for example), I'm just getting error about using the method (get/set/remove) on null.

Does anyone know or have an idea on how to overcome this issue, at least if it is possible without going back to the mode: spa?

P.S. Running npm run build|generate yields same files as for the normal vue (without the content, just the structure until the target element is readched) while in mode: spa.

Answer

Ivan Zhivolupov picture Ivan Zhivolupov · Jun 14, 2018

Okay, after around 12 hours trying to wrap my head around this issue, i've decided to go the 'dirty' way and create middleware which is doing, in my opinion, way to much processing on each request.

import CookieParser from 'cookieparser';

export default async function ({ store, req }) {
  if (!store.getters['account/check']) {
    if (!store.state.account.token) {
      if (process.server) {
        let requestCookies = CookieParser.parse(req.headers.cookie);
        if (requestCookies.hasOwnProperty('token')) {
          store.dispatch('account/saveToken', {
            token: requestCookies.token,
            remember: true
          });
        }
      }
    }
    if (store.state.account.token) {
      if (!store.state.account.user) {
         try {
           await store.dispatch('account/fetchUser');
         } catch (error) { }
      }
    }
  }
  return Promise.resolve();
}