question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Nuxt auth plugin not initiating after page refresh

See original GitHub issue

Steps to reproduce

(First please check that this issue is not already solved as described here)

  • Tell us what broke. The more detailed the better.
  • If you can, please create a simple example that reproduces the issue and link to a gist, jsbin, repo, etc.

Expected behavior

If user is signed in, a page refresh should keep them logged in.

Actual behavior

User is not authenticated, regardless of jwt-token being stored in localStorage or cookies

System configuration

Latest nuxt js and feathers vuex Node feathers API

nuxt.config.js:

  modules: [
    // Doc: https://bootstrap-vue.js.org
    'bootstrap-vue/nuxt',
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    '@nuxtjs/pwa',
    // Doc: https://github.com/nuxt-community/dotenv-module
    '@nuxtjs/dotenv',
    '@nuxtjs/toast',
    // '@nuxtjs/auth'
    'nuxt-client-init-module'
  ],

store/index.js (as per official documentation)

// ~/store/index.js
import {
  makeAuthPlugin,
  initAuth,
  hydrateApi,
  models
} from '~/plugins/feathers'
const auth = makeAuthPlugin({
  userService: 'users',
  state: {
    publicPages: [
      'login',
      'signup',
      'index',
      'terms-of-service',
      'privacy-policy'
    ]
  },
  actions: {
    onInitAuth({ state, dispatch }, payload) {
      if (payload) {
        dispatch('authenticate', {
          strategy: 'jwt',
          accessToken: state.accessToken
        })
          .then((result) => {
            // handle success like a boss
            console.log('loged in')
          })
          .catch((error) => {
            // handle error like a boss
            console.log(error)
          })
      }
    }
  }
})

const requireModule = require.context(
  // The path where the service modules live
  './services',
  // Whether to look in subfolders
  false,
  // Only include .js files (prevents duplicate imports`)
  /.js$/
)
const servicePlugins = requireModule
  .keys()
  .map((modulePath) => requireModule(modulePath).default)

export const modules = {
  // Custom modules
}

export const state = () => ({
  // Custom state
})

export const mutations = {
  // Custom mutations
}

export const actions = {
  // Custom actions
  nuxtServerInit({ commit, dispatch }, { req }) {
    return initAuth({
      commit,
      dispatch,
      req,
      moduleName: 'auth',
      cookieName: 'feathers-jwt'
    })
  },
  nuxtClientInit({ state, dispatch, commit }, context) {
    hydrateApi({ api: models.api })

    if (state.auth.accessToken) {
      return dispatch('auth/onInitAuth', state.auth.payload)
    }
  }
}

export const getters = {
  // Custom getters
}

export const plugins = [...servicePlugins, auth]

Module versions (especially the part that’s not working):

"@feathersjs/authentication-client": "^4.5.1",
"@feathersjs/configuration": "^2.0.6",
"@feathersjs/express": "^1.3.1",
"@feathersjs/feathers": "^3.3.1",
"@feathersjs/rest-client": "^4.5.1",
"@feathersjs/socketio-client": "^4.5.1",
"@nuxtjs/axios": "^5.9.5",
"@nuxtjs/dotenv": "^1.4.0",
"@nuxtjs/pwa": "^3.0.0-0",
"@nuxtjs/toast": "^3.3.0",
"@vue/composition-api": "^0.4.0",
"bootstrap": "^4.1.3",
"bootstrap-vue": "^2.0.0",
"consola": "^2.11.3",
"cookie-storage": "^6.0.0",
"cross-env": "^5.2.0",
"feathers-hooks-common": "^5.0.2",
"feathers-vuex": "^3.6.1",
"nuxt": "^2.0.0",
"nuxt-client-init-module": "^0.1.8",
"socket.io-client": "^2.3.0"

NodeJS version: v12.15.0

Operating System:

macos & docker

Browser Version: Latest Chrome

React Native Version: no react

Module Loader: NPM

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:6
  • Comments:13 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
ghostcommented, Apr 1, 2021

Hey guys I wanted to share a workaround that worked for me to get authenticated server side whereas @mategvo’s solution will only work client side which can cause problems.

The root of the problem comes from the fact that cookie-storage requires document to work properly which will not work server side to parse the feathers-jwt token.

Compounding that fact is that plugins/feathers from the full nuxt example has .configure(auth({ storage })) which isn’t yet aware of the req variable required to parse cookies server side so I cooked up a workaround. Bear in mind that this isn’t fully tested yet so there could be some gotchas further down the road so if you see one let me know.

First off, replace cookie-storage with universal-cookie

Then give it a decorate it with the required methods

class CookieStorage extends Cookies {
  get getItem() { return this.get; }
  get setItem() { return this.set; }
  get removeItem()  { return this.remove; }
}

Then, install cookie-universal-nuxt and refactor @mategvo 's code so that it will work on the server side too.

Here’s my full workaround:

// ~/plugins/authInit.js
import { storage } from './feathers';

const hashTokenAvailable = process.client && window.location.hash.indexOf('access_token' > -1);

export default async ({ store, $cookie }) => {
  // Give the cookie to the auth module's storage instance
  const cookie = $cookie.get('feathers-jwt');
  if (cookie) {
    storage.set('feathers-jwt', cookie);
  }

  if ((!store.state.auth.user && cookie) || hashTokenAvailable) {
    await store
      .dispatch('auth/authenticate')
      .then(() => {
        console.log('Authenticated');
      })
      .catch((e) => {
        console.error(e)
      })
  }
}
// ~/plugins/feathers.js
import feathers from '@feathersjs/feathers'
import rest from '@feathersjs/rest-client'
import axios from 'axios'
import socketio from '@feathersjs/socketio-client'
import auth from '@feathersjs/authentication-client'
import io from 'socket.io-client'
import Cookies from 'universal-cookie';
import { iff, discard } from 'feathers-hooks-common'
import feathersVuex, { initAuth, hydrateApi } from 'feathers-vuex'

const apiUrl = process.env.API_URL;

let socket
let restClient
// We won't use socket to comunicate from server to server
if (process.client) {
  socket = io(apiUrl, { transports: ['websocket'] })
} else {
  restClient = rest(apiUrl)
}
const transport = process.client ? socketio(socket) : restClient.axios(axios)

class CookieStorage extends Cookies {
  get getItem() { return this.get; }
  get setItem() { return this.set; }
  get removeItem()  { return this.remove; }
  // and any other required method as needed
}
const storage = new CookieStorage()

const feathersClient = feathers()
  .configure(transport)
  .configure(auth({ storage }))
  .hooks({
    before: {
      all: [
        iff(
          context => ['create', 'update', 'patch'].includes(context.method),
          discard('__id', '__isTemp')
        )
      ]
    }
  })

export default feathersClient

// Setting up feathers-vuex
const { makeServicePlugin, makeAuthPlugin, BaseModel, models, FeathersVuex } = feathersVuex(
  feathersClient,
  {
    serverAlias: 'api', // optional for working with multiple APIs (this is the default value)
    idField: '_id', // Must match the id field in your database table/collection
    whitelist: ['$regex', '$options'],
    enableEvents: process.client // Prevent memory leak
  }
)

export {
  makeAuthPlugin,
  makeServicePlugin,
  BaseModel,
  models,
  FeathersVuex,
  initAuth,
  hydrateApi,
  storage,
}

Obviously not the best solution here; hoping this SSR oversight gets fixed later.

0reactions
andrewharveycommented, Mar 16, 2020

Doesn’t work for you with SSR you mean? My project is a simple SPA, I forgot to mention I haven’t tested SSR, I don’t think it will work

That’s right I’m using ‘universal’ mode with Nuxt, but only when in dev mode not production do I see the issue anyway.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Nuxt JS auth.user object empties after refreshing the page
The auth module does not persist information about the user, so there needs to be a way to fetch the user's information on...
Read more >
Releases - nuxt auth docs
$auth instance is shared across Nuxt context (plugins, middleware, pages, etc). Options simplified; The token is no longer exposed in server response (As...
Read more >
How to make nuxt auth working with JWT - a definitive guide
We try getting those tokens from our cookies(plugins are executed on page load), and fallback to our constant interval first. If we have...
Read more >
Creating Server-side Rendered Vue.js Apps Using Nuxt.js
Open your browser to localhost:3000 and your project should be running. Not much different from creating a Vue Webpack project. However, when we...
Read more >
How To Implement Authentication in a Nuxt.js App
The app should be running on http://localhost:3000 . You can view the application in a web browser to see the default Vue application ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found