Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

SecretsSeeker's avatar

Custom auth for nuxt

Nuxt/auth module hurt my brain so long and today I created custom module:

First I have this store structure:

store/
-- index.js
-- mutations.js
-- actions.js
-- state.js
-- getters.js
middleware/
-- redirectIfAuth.js
-- redirectIfNotAuth.js
layouts/
default.vue -> has redirectIfNotAuth.js
guest.vue -> has redirectIfAuth.js
pages/
-- login/
---- index.vue -> uses guest.vue as layout
-- dashboard/
----- index.vue -> uses default.vue as layout without declaration

Inside Index.js I have:

import state from './state'
import * as actions from './actions'
import * as mutations from './mutations'
import * as getters from './getters'

export default {
  state,
  getters,
  mutations,
  actions,
  modules: {}
}

Inside State.js I have:

export default () => ({
  user: null,
  token: null,
  headers: null
})

Inside Actions.js I have:

const cookieparser = process.server ? require('cookieparser') : undefined
// importing server based cookie library

export async function nuxtServerInit ({ commit }, { req, res }) {

  // If we have any axios requests we need to add async/await
  // And since this works on server mode, we don't need to check is it server

  let token = null
  if (req.headers.cookie) {
    const parsed = cookieparser.parse(req.headers.cookie)
    try {
      token = parsed.authToken
    } catch (e) {
      console.log(e)
    }
  }
  // If we have token within cookies we get user data from api and we pass Autorization headers with token
  if (token !== null && token !== false) {
    await axios.get('/api/auth/me', {
      headers: {
        'Authorization': token
      }
    }).then((response) => {
      // If  we get user data we set it to store
      commit('setUser', response.data.data)
      commit('setToken', token)
      commit('setHeaders', token)
    }).catch((error) => {
      // If we get error, we should logout user by removing data within cookies and store
      // Additionally you can create specific code error on backend to check if token is expired or invalid
      // and then check for status code and then remove data
      commit('setUser', null)
      commit('setToken', null)
      res.setHeader('Set-Cookie', [`authToken=false; expires=Thu, 01 Jan 1970 00:00:00 GMT`])
      // This is only way I found useful for removing cookies from node server
      console.warn(error)
    })
  }
}

Inside Mutations.js I have:

export const setToken = (state, payload) => state.token = payload

export const setUser = (state, payload) => state.user = payload

export const setHeaders = (state, payload) => {
  state.headers = {
    headers: {
      'Authorization': payload
    }
  }
}

Inside Getters.js I have:

export const getUser = (state) => state.user
export const getToken = (state) => state.token
export const getHeaders = (state) => state.headers

Second I created two middlewares and it seems like nuxt middlewares work on both server and client sides, so I needed to require both libraries for server and client side Then I checked which side it is and then try to get token for further investigations If you include and don't check for server and client but use one of them, your templates wont render but show undefined errors for req on client instead and on server it wont show anything.

Inside redirectIfAuth.js I have:

const cookieparser = process.server ? require('cookieparser') : undefined
const Cookie = process.client ? require('js-cookie') : undefined
export default function ({ app, redirect, req }) {
  let token = null
  if (process.server) {
    if (req.headers.cookie) {
      const parsed = cookieparser.parse(req.headers.cookie)
      try {
        token = parsed.authToken
      } catch (e) {
        console.log(e)
      }
    }
  } else if (process.client) {
    token = Cookie.get('authToken')
  }
  if (token && token !== false) {
    app.store.commit('setToken', token)
    app.store.commit('setHeaders', token)
    if (app.store.state.user) {
      if (app.store.state.user.roles.includes('customer')) {
        return redirect({
          name: 'customer-slug',
          params: { slug: app.store.state.user.username }
        })
      } else if (app.store.state.user.roles.includes('admin')) {
        return redirect({
          name: 'dashboard'
        })
      } else {
        return redirect({
          name: 'index'
        })
      }
    } else {
      return redirect({
        name: 'index'
      })
    }
  }
}

Inside redirectIfNotAuth.js I have:

const cookieparser = process.server ? require('cookieparser') : undefined
const Cookie = process.client ? require('js-cookie') : undefined
export default function ({ app, redirect, route, req }) {
  let token = null
  if (process.server) {
    if (req.headers.cookie) {
      const parsed = cookieparser.parse(req.headers.cookie)
      try {
        token = parsed.authToken
      } catch (e) {
        console.log(e)
      }
    }
  } else if (process.client) {
    token = Cookie.get('authToken')
  }
  if (token === null || token === false) {
    return redirect({
      name: 'login',
      query: {
        redirect: route.fullPath
      }
    })
  }
}

Now we use these middlewares within pages or layouts as:

export default {
  middleware: ['redirectIfAuth']
}

Or

export default {
  middleware: ['redirectIfNotAuth']
}

Login:

async login () {
      if (this.form.email !== '' && this.form.password !== '') {
        await this.$axios.post('/api/auth/login', this.form).then((response) => {
          this.$store.commit('setUser', response.data.data)
          this.$store.commit('setToken', 'Bearer ' + response.data.meta.access_token)
          this.$store.commit('setHeaders', 'Bearer ' + response.data.meta.access_token)
          Cookie.set('authToken', 'Bearer ' + response.data.meta.access_token, { expires: 365 })
          // Cookie.set('authUser', response.data.data, { expires: 365 }) if you need user data within cookies
          if (this.$route.query.redirect) {
            this.$router.push(this.$route.query.redirect)
          }
          this.$router.push('/')
        })
      }
    }

Logout:

async logout () {
   await this.$axios.post('/api/auth/logout', {}, this.headers)
   // Cookie.remove('authUser') if exists
   Cookie.remove('authToken')
   this.$router.push('/')
}

I hope this helps someone or someone get idea from this to make something else. I had million problems with official nuxt auth and only this helped me sort things out...

0 likes
3 replies
woooms's avatar

I have the same problem, And I toke your code, and works like a charm! guys you should just delete Nuxt-auth moudle.

FallOutBoi's avatar

Umm one question, why in the middleware we're not verifying the tokens?

yannaing's avatar

I get an error "cannot find module cookieparser".

I run yarn add cookie-parser and change require('cookieparser') to require('cookie-parser')

And I got another error. cookieparser.parse is not a function

What should I do?

Please or to participate in this conversation.