Auth middleware with Nuxt and Firebase Nuxt Module in Static Mode

Viewed 1046

I'm trying to implement Firebase in a Nuxt app (static). I installed @nuxtjs/firebase, configured it, and make it worked with auth (both login and logout works). I want to lock the entire app behing a login.

But when i enable the middleware the app crash. This is because, I think, there is some additional step to do in order to make the module work in SSR. I think that in the server the middleware will trigger a redirect as the user is not set, am I right? How can I achieve a working middleware?

Code for middleware auth.js:

export default function ({ store, redirect }) {
    if (!store.state.user) {
        return redirect('/login')
    }
}

Code for store index.js

export const state = () => ({
    user: null,
    userData: {}
})

export const getters = {

}

export const mutations = {
    onAuthStateChangedMutation(state, {authUser}){
        if (!authUser) {
            state.user = null
        } else {
            const { uid, email } = authUser
            state.user = { uid, email }        
        }
    },

    setUserData(state, payload){
        state.userData = payload
    }
}

export const actions = {
    async onAuthStateChangedAction({commit}, {authUser}){
        if (!authUser) {
            state.userData = {}
        } else {
            try{
                const userRef = await this.$fire.firestore.collection('users').doc(authUser.uid).get()
                const userData = await userRef.data()
                commit('setUserData', userData)
            }
            catch(e){
                console.log(e)
            }
        }
    }
}

On nuxt.config

  firebase: {
    services:{
      auth:{
        ssr: true,
        initialize:{
          onAuthStateChangedMutation: 'onAuthStateChangedMutation',
          onAuthStateChangedAction: 'onAuthStateChangedAction',
        }
      },
      firestore: true,
      analytics: true
    }
  },
  
  router:{
    middleware: 'auth'
  }
1 Answers

I managed to make it work, merging the infos on the nuxtjs firebase docs and my use case. Though if anyone have better ideas or spot a vulnerability in my solution feel free to contribute:

Code for store index.js

export const state = () => ({
    user: null,
    userData: null,
    isUserReady: false
})

export const getters = {

}

export const mutations = {
    onAuthStateChangedMutation(state, {authUser}){
        if (!authUser) {
            state.user = null
        } else {
            const { uid, email } = authUser
            state.user = { uid, email }
        }
    },

    clearUserData(state){
        state.isUserReady = false
        state.userData = null
    },

    setUserData(state, payload){
        state.userData = payload
        state.isUserReady = true
    }
}

export const actions = {
    async nuxtServerInit({ commit }, { res }) {
        if (res && res.locals && res.locals.user) {
            const { ...authUser } = res.locals.user
            commit('onAuthStateChangedMutation', { authUser })
        }
    },

    async onAuthStateChangedAction({commit}, {authUser}){
        if (!authUser) {
            commit('clearUserData')
        } else {
            try{
                const userRef = await this.$fire.firestore.collection('users').doc(authUser.uid).get()
                const userData = await userRef.data()
                commit('setUserData', userData)
            }
            catch(e){
                console.log(e)
            }
        }
    }
}

In nuxt.config.js

  firebase: {
    config:{
      ...
    },
    services:{
      auth:{
        initialize:{
          onAuthStateChangedMutation: 'onAuthStateChangedMutation',
          onAuthStateChangedAction: 'onAuthStateChangedAction',
        }
      },
      firestore: true,
    }
  },

  pwa: {
    manifest: {
      lang: 'en'
    },
    workbox: {
      importScripts: [
        '/firebase-auth-sw.js'
      ],
      dev: true
    }
  }

With these settings I am able to deploy the app (ssr: false, target: "static") on Netlify, and a user can login, the login is persistent even with a page reload.

Related