Nuxt.js: Get localStorage token from nuxtServerInit

Created on 31 Jan 2018  路  3Comments  路  Source: nuxt/nuxt.js

So my problems is how would I get the localStorage jwt token that i've been using to pass on the header for my separate apollo graphql server

Below is how I try to setup the token
store/index.js

import Vuex from "vuex";
import { Auth, Login } from "~/apollo/gql/Auth.gql";
import Cookie from "js-cookie";
export const state = () => ({
  auth: null,
  token: ""
});

export const mutations = {
  SET_TOKEN(state, data) {
    state.token = data;
  }
};
export const actions = {
  async nuxtServerInit(store, context) {
    let client = context.app.apolloProvider.defaultClient;
    let { data } = await client.query({
      query: Auth,
      fetchPolicy: "network-only"
    });
    const token = Cookie.get("token");
    console.log(token);
    console.log(context, store, data);
  },
  async login({ commit }, data) {
    const client = this.app.apolloProvider.defaultClient;

    const { data: val } = await client.mutate({
      mutation: Login,
      variables: {
        data
      }
    });

    localStorage.setItem("token", val.result.token);
    Cookie.set("token", val.result.token);
    const token = Cookie.get("token");
    console.log(token);
    commit("SET_TOKEN", val.result.token);
  }
};

I'll use my login function to send a mutation request on my api server then get that token back

It works when i Login but when on the case of reloading the page

the token is not set on nuxtServerInit so what I wanted to do is how do I store the token somehow on the request object of the nuxt server so whenever I try to check the user if he/she is authenticated I will just set the token on startup on the Token state

Also tried the cookie library

but seems I don't get the idea how cookie works maybe give me a simple point of view of how cookie session work?

I tried to find the session property on the request object but it's not there

this some part of the config for apollo-client

// auth token
  let getToken = () =>
    process.server ? ctx.req.session : localStorage.getItem("token");

  // middleware
  const middlewareLink = new ApolloLink((operation, forward) => {
    if (process.server) console.log(ctx);
    operation.setContext({
      headers: {
        authorization: `Bearer ${getToken()}`
      }
    });
    return forward(operation);
  });

  const wsLink = process.client
    ? new WebSocketLink({
        uri: process.env.SUBSCRIPTIONS_ENDPOINT,
        options: {
          reconnect: true,
          connectionParams: () => {
            const token = getToken();
            return {
              Authorization: token ? `Bearer ${token}` : null
            };
          }
        }
      })
    : "";

This question is available on Nuxt.js community (#c2373)

Most helpful comment

You cannot get localstorage from server side, localstorage is a client only API, your approach with cookies is the right one. You could simplify the code by using a universal cookie plugin like this one: https://github.com/reactivestack/cookies/tree/master/packages/universal-cookie

I think I'd avoid using localstorage at all.

All 3 comments

Okay I managed to fix this issue using two libraries

cookie and js-cookie

here is the sample code

import Vuex from "vuex";
import { Auth, Login } from "~/apollo/gql/Auth.gql";
import Cookies from "js-cookie";
import cookie from "cookie";
export const state = () => ({
  auth: null,
  token: ""
});

export const mutations = {
  SET_TOKEN(state, data) {
    state.token = data;
  },
  SET_AUTH(state, data) {
    state.auth = data;
  }
};
export const actions = {
  async nuxtServerInit(store, context) {
    let client = context.app.apolloProvider.defaultClient;
    let { token } = cookie.parse(context.req.headers.cookie);
    store.commit("SET_TOKEN", token);
  },
  async login({ commit, dispatch }, data) {
    const client = this.app.apolloProvider.defaultClient;

    const { data: val } = await client.mutate({
      mutation: Login,
      variables: {
        data
      }
    });
    const token = val.result.token;
    localStorage.setItem("token", token);
    Cookies.set("token", token);
    commit("SET_TOKEN", token);
    return dispatch("fetchAuth");
  },
  async logout({ commit }) {
    localStorage.removeItem("token");
    Cookies.remove("token");
    commit("SET_TOKEN", null);
    commit("SET_AUTH", null);
  },
  async fetchAuth({ commit }) {
    const client = this.app.apolloProvider.defaultClient;
    let { data } = await client.query({
      query: Auth,
      fetchPolicy: "network-only"
    });
    console.log(data);
    commit("SET_AUTH", data.result);
  }
};

Any ideas to improve this or refactor

You cannot get localstorage from server side, localstorage is a client only API, your approach with cookies is the right one. You could simplify the code by using a universal cookie plugin like this one: https://github.com/reactivestack/cookies/tree/master/packages/universal-cookie

I think I'd avoid using localstorage at all.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gary149 picture gary149  路  3Comments

uptownhr picture uptownhr  路  3Comments

jaredreich picture jaredreich  路  3Comments

vadimsg picture vadimsg  路  3Comments

maicong picture maicong  路  3Comments